# Path: toto/tasks.py
# class TaskQueue():
#   '''Instances will run up to ``thread_count`` tasks at a time
#   whenever there are tasks in the queue. Theads will be killed
#   if unused for longer than ``idle_timeout`` seconds.
#   '''
# 
#   def __init__(self, thread_count=1, idle_timeout=60, name='TaskQueue'):
#     self.tasks = deque()
#     self.running = False
#     self.condition = Condition()
#     self.threads = set()
#     self.idle_timeout = idle_timeout
#     self.thread_count = thread_count
#     self.name = name
# 
#   def add_task(self, fn, *args, **kwargs):
#     '''Add the function ``fn`` to the queue to be invoked with
#     ``args`` and ``kwargs`` as arguments. If the ``TaskQueue``
#     is not currently running, it will be started now.
#     '''
#     with self.condition:
#       self.tasks.append((fn, args, kwargs))
#       self.condition.notify()
#       self.run()
# 
#   def yield_task(self, fn, *args, **kwargs):
#     '''Like add_task but will call the function as a coroutine, allowing you
#     to yield the return value from within a function decorated with ``@tornado.gen.coroutine``
#     or ``@tornado.gen.engine``.
# 
#     Usage::
# 
#       def add(arg1, arg2):
#         return arg1 + arg2
# 
#       @tornado.gen.engine
#       def caller():
#         value = yield TaskQueue.instance('myqueue').yield_task(add, 1, 2)
#         print value #prints 3
# 
#     '''
# 
#     ioloop = IOLoop.current()
#     future = Future()
#     def call():
#       result = None
#       error = None
#       try:
#         result = fn(*args, **kwargs)
#       except Exception as e:
#         ioloop.add_callback(future.set_exc_info, exc_info())
#       else:
#         # tornado future is not threadsafe
#         ioloop.add_callback(future.set_result, result)
#     self.add_task(call)
#     return future
# 
#   def run(self):
#     '''Start processing jobs in the queue. You should not need
#     to call this as ``add_task`` automatically starts the queue.
#     Processing threads will stop when there are no jobs available
#     in the queue for at least ``idle_timeout`` seconds.
#     '''
#     with self.condition:
#       if len(self.threads) >= self.thread_count:
#         return
#       thread = self.__TaskLoop(self)
#       self.threads.add(thread)
#       thread.start()
# 
#   def __len__(self):
#     '''Returns the number of active threads plus the number of
#     queued tasks/'''
#     return len(self.threads) + len(self.tasks)
# 
#   @classmethod
#   def instance(cls, name, thread_count=1, idle_timeout=60):
#     '''A convenience method for accessing shared instances of ``TaskQueue``.
#     If ``name`` references an existing instance created with this method,
#     that instance will be returned. Otherwise, a new ``TaskQueue`` will be
#     instantiated with ``thread_count`` threads and the specified ``idle_timeout``
#     then stored under ``name``.
# 
#     All arguments after name are ignored after the queue is created.
#     '''
#     if not hasattr(cls, '_task_queues'):
#       cls._task_queues = {}
#     try:
#       return cls._task_queues[name]
#     except KeyError:
#       cls._task_queues[name] = cls(thread_count, idle_timeout, name)
#       return cls._task_queues[name]
# 
#   class __TaskLoop(Thread):
# 
#     thread_id = count()
# 
#     def __init__(self, queue):
#       Thread.__init__(self, name='%s-%d' % (queue.name, self.thread_id.next()))
#       self.daemon = True
#       self.queue = queue
#       self.condition = self.queue.condition
#       self.tasks = self.queue.tasks
#       self.idle_timeout = self.queue.idle_timeout
#       self.threads = self.queue.threads
#       self.in_use = True
# 
#     def run(self):
#       try:
#         while 1:
#           with self.condition:
#             if not len(self.tasks):
#               self.condition.wait(self.idle_timeout)
#             try:
#               task = self.tasks.popleft()
#             except IndexError:
#               logging.debug('Idle timeout: %s' % self.name)
#               self.threads.remove(self)
#               self.in_use = False
#               return
#           try:
#             task[0](*task[1], **task[2])
#           except Exception as e:
#             logging.error(traceback.format_exc())
#       finally:
#         with self.condition:
#           if self.in_use:
#             self.threads.remove(self)
#             self.in_use = False


from toto.invocation import *
from toto.tasks import TaskQueue
from time import sleep
from tornado.gen import coroutine, Return, Task, Callback, Wait

@coroutine
def invoke(handler, parameters):
  def respond(params):
    sleep(0.1)
    return {'parameters': parameters}
  def return_true():
    sleep(0.1)
    return True

  response = TaskQueue.instance('test1').yield_task(respond, parameters)

# Path: toto/tasks.py
# class TaskQueue():
#   '''Instances will run up to ``thread_count`` tasks at a time
#   whenever there are tasks in the queue. Theads will be killed
#   if unused for longer than ``idle_timeout`` seconds.
#   '''
# 
#   def __init__(self, thread_count=1, idle_timeout=60, name='TaskQueue'):
#     self.tasks = deque()
#     self.running = False
#     self.condition = Condition()
#     self.threads = set()
#     self.idle_timeout = idle_timeout
#     self.thread_count = thread_count
#     self.name = name
# 
#   def add_task(self, fn, *args, **kwargs):
#     '''Add the function ``fn`` to the queue to be invoked with
#     ``args`` and ``kwargs`` as arguments. If the ``TaskQueue``
#     is not currently running, it will be started now.
#     '''
#     with self.condition:
#       self.tasks.append((fn, args, kwargs))
#       self.condition.notify()
#       self.run()
# 
#   def yield_task(self, fn, *args, **kwargs):
#     '''Like add_task but will call the function as a coroutine, allowing you
#     to yield the return value from within a function decorated with ``@tornado.gen.coroutine``
#     or ``@tornado.gen.engine``.
# 
#     Usage::
# 
#       def add(arg1, arg2):
#         return arg1 + arg2
# 
#       @tornado.gen.engine
#       def caller():
#         value = yield TaskQueue.instance('myqueue').yield_task(add, 1, 2)
#         print value #prints 3
# 
#     '''
# 
#     ioloop = IOLoop.current()
#     future = Future()
#     def call():
#       result = None
#       error = None
#       try:
#         result = fn(*args, **kwargs)
#       except Exception as e:
#         ioloop.add_callback(future.set_exc_info, exc_info())
#       else:
#         # tornado future is not threadsafe
#         ioloop.add_callback(future.set_result, result)
#     self.add_task(call)
#     return future
# 
#   def run(self):
#     '''Start processing jobs in the queue. You should not need
#     to call this as ``add_task`` automatically starts the queue.
#     Processing threads will stop when there are no jobs available
#     in the queue for at least ``idle_timeout`` seconds.
#     '''
#     with self.condition:
#       if len(self.threads) >= self.thread_count:
#         return
#       thread = self.__TaskLoop(self)
#       self.threads.add(thread)
#       thread.start()
# 
#   def __len__(self):
#     '''Returns the number of active threads plus the number of
#     queued tasks/'''
#     return len(self.threads) + len(self.tasks)
# 
#   @classmethod
#   def instance(cls, name, thread_count=1, idle_timeout=60):
#     '''A convenience method for accessing shared instances of ``TaskQueue``.
#     If ``name`` references an existing instance created with this method,
#     that instance will be returned. Otherwise, a new ``TaskQueue`` will be
#     instantiated with ``thread_count`` threads and the specified ``idle_timeout``
#     then stored under ``name``.
# 
#     All arguments after name are ignored after the queue is created.
#     '''
#     if not hasattr(cls, '_task_queues'):
#       cls._task_queues = {}
#     try:
#       return cls._task_queues[name]
#     except KeyError:
#       cls._task_queues[name] = cls(thread_count, idle_timeout, name)
#       return cls._task_queues[name]
# 
#   class __TaskLoop(Thread):
# 
#     thread_id = count()
# 
#     def __init__(self, queue):
#       Thread.__init__(self, name='%s-%d' % (queue.name, self.thread_id.next()))
#       self.daemon = True
#       self.queue = queue
#       self.condition = self.queue.condition
#       self.tasks = self.queue.tasks
#       self.idle_timeout = self.queue.idle_timeout
#       self.threads = self.queue.threads
#       self.in_use = True
# 
#     def run(self):
#       try:
#         while 1:
#           with self.condition:
#             if not len(self.tasks):
#               self.condition.wait(self.idle_timeout)
#             try:
#               task = self.tasks.popleft()
#             except IndexError:
#               logging.debug('Idle timeout: %s' % self.name)
#               self.threads.remove(self)
#               self.in_use = False
#               return
#           try:
#             task[0](*task[1], **task[2])
#           except Exception as e:
#             logging.error(traceback.format_exc())
#       finally:
#         with self.condition:
#           if self.in_use:
#             self.threads.remove(self)
#             self.in_use = False


# Path: tests/web_methods/return_value_task_coroutine.py
from toto.invocation import *
from toto.tasks import TaskQueue
from time import sleep
from tornado.gen import coroutine, Return, Task, Callback, Wait


@coroutine
def invoke(handler, parameters):
  def respond(params):
    sleep(0.1)
    return {'parameters': parameters}
  def return_true():
    sleep(0.1)
    return True

  response = TaskQueue.instance('test1').yield_task(respond, parameters)

  value = TaskQueue.instance('test2').yield_task(return_true)