# Path: pyactor/green_thread/channel.py
# class Channel(Queue):
#     """
#     Channel is the main communication mechanism between actors. It is
#     actually a simple facade to the gevent.Queue 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 the constants in util.py (:mod:`pyactor.util`).
#         """
#         return self.get(timeout=timeout)
# 
# Path: pyactor/exceptions.py
# class PyActorTimeoutError(Exception):
#     """Wait time expired."""
# 
#     def __init__(self, method='Not specified'):
#         self.method = method
# 
#     def __str__(self):
#         return f"Timeout triggered: {self.method!r}"
# 
# class FutureError(Exception):
#     """Some problem with the Future."""
# 
#     def __init__(self, value='Not specified'):
#         self.value = value
# 
#     def __str__(self):
#         return f"Future ERROR: {self.value!r}"
# 
# Path: pyactor/util.py
# TELL = 'TELL'
# 
# FUTURE = 'FUTURE'
# 
# TYPE = 'TYPE'
# 
# METHOD = 'METHOD'
# 
# PARAMS = 'PARAMS'
# 
# CHANNEL = 'CHANNEL'
# 
# TO = 'TO'
# 
# Path: pyactor/util.py
# def get_current():
#     if core_type == 'thread':
#         current = current_thread()
#     else:
#         current = getcurrent()
#     for host in hosts.values():
#         if current in host.threads.keys():
#             return host.actors[host.threads[current]]
#         elif current in host.pthreads.keys():
#             return host.actors[host.pthreads[current]]
# 
# def get_host():
#     if core_type == 'thread':
#         current = current_thread()
#     else:
#         current = getcurrent()
#     for host in hosts.values():
#         if current in host.threads.keys():
#             return host
#         elif current in host.pthreads.keys():
#             return host
#     return main_host
# 
# RPC_ID = 'RPC_ID'
# 
# RESULT = 'RESULT'


import uuid
from gevent import spawn
from gevent.event import Event
from .channel import Channel
from ..exceptions import PyActorTimeoutError, FutureError
from ..util import TELL, FUTURE, TYPE, METHOD, PARAMS, CHANNEL, TO
from ..util import get_current, get_host, RPC_ID, RESULT
            if the future has not been completed. None, the default,
            sets no limit.
        :returns: The exception raised by the call that the future
            represents or None if the call completed without raising.
        :raises: TimeoutError: If the timeout is reached before the
            future ends execution.
        """
        # with self.__condition:
        if self.__state == FINISHED:
            return self.__exception

        self.__condition.wait(timeout)

        if self.__state == FINISHED:
            return self.__exception
        else:
            raise PyActorTimeoutError(f"Future: {self.__method!r}")

    def send_work(self):
        """
        Sends the query to the actor for it to start executing the work.

        It is possible to execute once again a future that has finished
        if necessary (overwriting the results), but only one execution
        at a time.
        """
        if self.__set_running():
            # msg = FutureRequest(FUTURE, self.__method, self.__params,
            #                     self.__channel, self.__target, self.__id)
            msg = {TYPE: FUTURE, METHOD: self.__method, PARAMS: self.__params,

# Path: pyactor/green_thread/channel.py
# class Channel(Queue):
#     """
#     Channel is the main communication mechanism between actors. It is
#     actually a simple facade to the gevent.Queue 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 the constants in util.py (:mod:`pyactor.util`).
#         """
#         return self.get(timeout=timeout)
# 
# Path: pyactor/exceptions.py
# class PyActorTimeoutError(Exception):
#     """Wait time expired."""
# 
#     def __init__(self, method='Not specified'):
#         self.method = method
# 
#     def __str__(self):
#         return f"Timeout triggered: {self.method!r}"
# 
# class FutureError(Exception):
#     """Some problem with the Future."""
# 
#     def __init__(self, value='Not specified'):
#         self.value = value
# 
#     def __str__(self):
#         return f"Future ERROR: {self.value!r}"
# 
# Path: pyactor/util.py
# TELL = 'TELL'
# 
# FUTURE = 'FUTURE'
# 
# TYPE = 'TYPE'
# 
# METHOD = 'METHOD'
# 
# PARAMS = 'PARAMS'
# 
# CHANNEL = 'CHANNEL'
# 
# TO = 'TO'
# 
# Path: pyactor/util.py
# def get_current():
#     if core_type == 'thread':
#         current = current_thread()
#     else:
#         current = getcurrent()
#     for host in hosts.values():
#         if current in host.threads.keys():
#             return host.actors[host.threads[current]]
#         elif current in host.pthreads.keys():
#             return host.actors[host.pthreads[current]]
# 
# def get_host():
#     if core_type == 'thread':
#         current = current_thread()
#     else:
#         current = getcurrent()
#     for host in hosts.values():
#         if current in host.threads.keys():
#             return host
#         elif current in host.pthreads.keys():
#             return host
#     return main_host
# 
# RPC_ID = 'RPC_ID'
# 
# RESULT = 'RESULT'


# Path: pyactor/green_thread/future.py
import uuid
from gevent import spawn
from gevent.event import Event
from .channel import Channel
from ..exceptions import PyActorTimeoutError, FutureError
from ..util import TELL, FUTURE, TYPE, METHOD, PARAMS, CHANNEL, TO
from ..util import get_current, get_host, RPC_ID, RESULT

            if the future has not been completed. None, the default,
            sets no limit.
        :returns: The exception raised by the call that the future
            represents or None if the call completed without raising.
        :raises: TimeoutError: If the timeout is reached before the
            future ends execution.
        """
        # with self.__condition:
        if self.__state == FINISHED:
            return self.__exception

        self.__condition.wait(timeout)

        if self.__state == FINISHED:
            return self.__exception
        else:
            raise PyActorTimeoutError(f"Future: {self.__method!r}")

    def send_work(self):
        """
        Sends the query to the actor for it to start executing the work.

        It is possible to execute once again a future that has finished
        if necessary (overwriting the results), but only one execution
        at a time.
        """
        if self.__set_running():
            # msg = FutureRequest(FUTURE, self.__method, self.__params,
            #                     self.__channel, self.__target, self.__id)
            msg = {TYPE: FUTURE, METHOD: self.__method, PARAMS: self.__params,

                   CHANNEL: self.__channel, TO: self.__target,