# Path: pyactor/thread/actor.py
# class Actor(ActorRef):
#     """
#     Actor is the instance of an object to which is possible to access
#     and invoke its methods remotely. Main element of the model. The
#     host is the one to create them (spawning -> see :meth:`~.spawn`).
# 
#     :param str. url: URL where the actor is running.
#     :param class klass: class type for the actor.
#     :param klass obj: instance of the *klass* class to attach to the
#         actor.
#     """
# 
#     def __init__(self, url, klass, obj):
#         super(Actor, self).__init__(url, klass)
#         self._obj = obj
#         self.id = obj.id
#         self.running = True
#         self.thread = None
#         self.future_manager = FutureManager()
# 
#     def __process_queue(self):
#         while self.running:
#             message = self.channel.receive()
#             self.receive(message)
# 
#     def is_alive(self):
#         """
#         :return: (*bool.*) identifies the current state of the actor.
#             **True** if it is running.
#         """
#         return self.running
# 
#     def receive(self, msg):
#         """
#         The message received from the queue specifies a method of the
#         class the actor represents. This invokes it. If the
#         communication is an ASK, sends the result back
#         to the channel included in the message as an ASK_RESPONSE.
# 
#         If it is a FUTURE, generates a FUTURE_RESPONSE
#         to send the result to the manager.
# 
#         :param msg: The message is a dictionary using the constants
#             defined in util.py (:mod:`pyactor.util`).
#         """
#         if msg[TYPE] == TELL and msg[METHOD] == 'stop':
#             self.running = False
#             self.future_manager.stop()
#         else:
#             try:
#                 invoke = getattr(self._obj, msg[METHOD])
#                 params = msg[PARAMS]
#                 result = invoke(*params[0], **params[1])
#             except Exception as e:
#                 if msg[TYPE] == TELL:
#                     print(e)
#                     return
#                 result = e
#             self.send_response(result, msg)
# 
#     def send_response(self, result, msg):
#         if msg[TYPE] == ASK:
#             response = {TYPE: ASK_RESPONSE, RESULT: result,
#                         RPC_ID: msg[RPC_ID] if RPC_ID in msg.keys() else None}
#             msg[CHANNEL].send(response)
#         elif msg[TYPE] == FUTURE:
#             response = {TYPE: FUTURE_RESPONSE, RPC_ID: msg[RPC_ID],
#                         RESULT: result}
#             msg[CHANNEL].send(response)
# 
#     def run(self):
#         """
#         Creates the actor thread which will process the channel queue
#         while the actor :meth:`is_alive`, making it able to receive
#         queries.
#         """
#         self.thread = Thread(target=self.__process_queue)
#         self.thread.start()
# 
# Path: pyactor/thread/channel.py
# class Channel(Queue):
#     """
#     Channel is the main communication mechanism between actors. It is
#     actually a simple facade to the queue.Queue python class.
#     """
# 
#     def __init__(self):
#         Queue.__init__(self)
# 
#     def send(self, msg):
#         """
#         It sends a message to the current channel.
# 
#         :param msg: The message sent to an actor. It is a dictionary using
#             the constants in util.py (:mod:`pyactor.util`).
#         """
#         self.put(msg)
# 
#     def receive(self, timeout=None):
#         """
#         It receives a message from the channel, blocking the calling
#         thread until the response is received, or the timeout is
#         triggered.
# 
#         :param int timeout: timeout to wait for messages. If none
#             provided it will block until a message arrives.
#         :return: returns a message sent to the channel. It is a dictionary
#             using the constants in util.py (:mod:`pyactor.util`).
#         """
#         return self.get(timeout=timeout)
# 
# Path: pyactor/util.py
# FUTURE = 'FUTURE'
# 
# ASK_RESPONSE = 'ASK_RESPONSE'
# 
# FUTURE_RESPONSE = 'FUTURE_RESPONSE'
# 
# Path: pyactor/util.py
# TYPE = 'TYPE'
# 
# METHOD = 'METHOD'
# 
# TELL = 'TELL'
# 
# ASK = 'ASK'
# 
# CHANNEL = 'CHANNEL'
# 
# FROM = 'FROM'
# 
# TO = 'TO'
# 
# RPC_ID = 'RPC_ID'


import uuid
import pickle
import traceback
from urllib.parse import urlparse
from importlib import import_module
from .actor import Actor
from .channel import Channel
from ..util import FUTURE, ASK_RESPONSE, FUTURE_RESPONSE
from ..util import TYPE, METHOD, TELL, ASK, CHANNEL, FROM, TO, RPC_ID
                    self.get_sink(msg[TO]).send(msg)
                elif msg[TYPE] == ASK_RESPONSE or msg[TYPE] == FUTURE_RESPONSE:
                    try:
                        if msg[RPC_ID] in self.executing.keys():
                            sink = self.get_sink(self.executing[msg[RPC_ID]])
                            sink.send(msg)
                            del self.executing[msg[RPC_ID]]
                    except TypeError as p:
                        print("Pickle ERR: impossible to marshall a return." +
                              " Returning a Proxy without the method in " +
                              f"_ref? {p}")
                    except Exception as e:
                        print(("Error sending a response to {!r}. "
                               .format(self.executing[msg[RPC_ID]])) + str(e))
                        del self.executing[msg[RPC_ID]]
                elif msg[TYPE] == FUTURE:
                    rpc_id = msg[RPC_ID]
                    self.pending[rpc_id] = msg[CHANNEL]
                    del msg[CHANNEL]
                    msg[FROM] = self.url
                    self.get_sink(msg[TO]).send(msg)
            except TypeError as p:
                print("Pickle ERROR: impossible to marshall a parameter." +
                      f"Passing a Proxy without the method in _ref? {p}")
            except Exception as e:
                print(e)

    def on_message(self, msg):
        try:
            msg = pickle.loads(msg.data)

# Path: pyactor/thread/actor.py
# class Actor(ActorRef):
#     """
#     Actor is the instance of an object to which is possible to access
#     and invoke its methods remotely. Main element of the model. The
#     host is the one to create them (spawning -> see :meth:`~.spawn`).
# 
#     :param str. url: URL where the actor is running.
#     :param class klass: class type for the actor.
#     :param klass obj: instance of the *klass* class to attach to the
#         actor.
#     """
# 
#     def __init__(self, url, klass, obj):
#         super(Actor, self).__init__(url, klass)
#         self._obj = obj
#         self.id = obj.id
#         self.running = True
#         self.thread = None
#         self.future_manager = FutureManager()
# 
#     def __process_queue(self):
#         while self.running:
#             message = self.channel.receive()
#             self.receive(message)
# 
#     def is_alive(self):
#         """
#         :return: (*bool.*) identifies the current state of the actor.
#             **True** if it is running.
#         """
#         return self.running
# 
#     def receive(self, msg):
#         """
#         The message received from the queue specifies a method of the
#         class the actor represents. This invokes it. If the
#         communication is an ASK, sends the result back
#         to the channel included in the message as an ASK_RESPONSE.
# 
#         If it is a FUTURE, generates a FUTURE_RESPONSE
#         to send the result to the manager.
# 
#         :param msg: The message is a dictionary using the constants
#             defined in util.py (:mod:`pyactor.util`).
#         """
#         if msg[TYPE] == TELL and msg[METHOD] == 'stop':
#             self.running = False
#             self.future_manager.stop()
#         else:
#             try:
#                 invoke = getattr(self._obj, msg[METHOD])
#                 params = msg[PARAMS]
#                 result = invoke(*params[0], **params[1])
#             except Exception as e:
#                 if msg[TYPE] == TELL:
#                     print(e)
#                     return
#                 result = e
#             self.send_response(result, msg)
# 
#     def send_response(self, result, msg):
#         if msg[TYPE] == ASK:
#             response = {TYPE: ASK_RESPONSE, RESULT: result,
#                         RPC_ID: msg[RPC_ID] if RPC_ID in msg.keys() else None}
#             msg[CHANNEL].send(response)
#         elif msg[TYPE] == FUTURE:
#             response = {TYPE: FUTURE_RESPONSE, RPC_ID: msg[RPC_ID],
#                         RESULT: result}
#             msg[CHANNEL].send(response)
# 
#     def run(self):
#         """
#         Creates the actor thread which will process the channel queue
#         while the actor :meth:`is_alive`, making it able to receive
#         queries.
#         """
#         self.thread = Thread(target=self.__process_queue)
#         self.thread.start()
# 
# Path: pyactor/thread/channel.py
# class Channel(Queue):
#     """
#     Channel is the main communication mechanism between actors. It is
#     actually a simple facade to the queue.Queue python class.
#     """
# 
#     def __init__(self):
#         Queue.__init__(self)
# 
#     def send(self, msg):
#         """
#         It sends a message to the current channel.
# 
#         :param msg: The message sent to an actor. It is a dictionary using
#             the constants in util.py (:mod:`pyactor.util`).
#         """
#         self.put(msg)
# 
#     def receive(self, timeout=None):
#         """
#         It receives a message from the channel, blocking the calling
#         thread until the response is received, or the timeout is
#         triggered.
# 
#         :param int timeout: timeout to wait for messages. If none
#             provided it will block until a message arrives.
#         :return: returns a message sent to the channel. It is a dictionary
#             using the constants in util.py (:mod:`pyactor.util`).
#         """
#         return self.get(timeout=timeout)
# 
# Path: pyactor/util.py
# FUTURE = 'FUTURE'
# 
# ASK_RESPONSE = 'ASK_RESPONSE'
# 
# FUTURE_RESPONSE = 'FUTURE_RESPONSE'
# 
# Path: pyactor/util.py
# TYPE = 'TYPE'
# 
# METHOD = 'METHOD'
# 
# TELL = 'TELL'
# 
# ASK = 'ASK'
# 
# CHANNEL = 'CHANNEL'
# 
# FROM = 'FROM'
# 
# TO = 'TO'
# 
# RPC_ID = 'RPC_ID'


# Path: pyactor/thread/rpcactor.py
import uuid
import pickle
import traceback
from urllib.parse import urlparse
from importlib import import_module
from .actor import Actor
from .channel import Channel
from ..util import FUTURE, ASK_RESPONSE, FUTURE_RESPONSE
from ..util import TYPE, METHOD, TELL, ASK, CHANNEL, FROM, TO, RPC_ID

                    self.get_sink(msg[TO]).send(msg)
                elif msg[TYPE] == ASK_RESPONSE or msg[TYPE] == FUTURE_RESPONSE:
                    try:
                        if msg[RPC_ID] in self.executing.keys():
                            sink = self.get_sink(self.executing[msg[RPC_ID]])
                            sink.send(msg)
                            del self.executing[msg[RPC_ID]]
                    except TypeError as p:
                        print("Pickle ERR: impossible to marshall a return." +
                              " Returning a Proxy without the method in " +
                              f"_ref? {p}")
                    except Exception as e:
                        print(("Error sending a response to {!r}. "
                               .format(self.executing[msg[RPC_ID]])) + str(e))
                        del self.executing[msg[RPC_ID]]
                elif msg[TYPE] == FUTURE:
                    rpc_id = msg[RPC_ID]
                    self.pending[rpc_id] = msg[CHANNEL]
                    del msg[CHANNEL]
                    msg[FROM] = self.url
                    self.get_sink(msg[TO]).send(msg)
            except TypeError as p:
                print("Pickle ERROR: impossible to marshall a parameter." +
                      f"Passing a Proxy without the method in _ref? {p}")
            except Exception as e:
                print(e)

    def on_message(self, msg):
        try:
            msg = pickle.loads(msg.data)

            if msg[TYPE] == TELL: