def asynchronous(coroutine): """ Allows a function to not use explicit callback functions to respond to asynchronous events. """ if not isgeneratorfunction(coroutine): # the "coroutine" isn't actually a coroutine; just return # its result like tornado.web.asynchronous would do return coroutine web_async_coroutine = web_async(coroutine) @functools.wraps(coroutine) def run_async_routine(*args, **kwargs): # we check if we're an instancemethod of RequestHandler for better # intergration if len(args) > 0 and isinstance(args[0], RequestHandler): CoroutineRunner(io_loop[0], web_async_coroutine(*args, **kwargs), args[0]) else: CoroutineRunner(io_loop[0], coroutine(*args, **kwargs), None) return run_async_routine
def run_async_routine(*args, **kwargs): if len(args) > 0 and isinstance(args[0], RequestHandler): routine = web_async(coroutine) web_handler = args[0] else: routine = coroutine web_handler = None gen = routine(*args, **kwargs) if not inspect.isgenerator(gen): # the "coroutine" isn't actually a coroutine; just return # its result like tornado.web.asynchronous would do return gen work = [None] def execute_work(): return work[0](callback_proxy) def callback_proxy(*args): is_err = lambda val: isinstance(val, Exception) try: if len(args) > 0: if is_err(args[-1]): work[0] = gen.throw(args[-1]) elif (hasattr(args[0], 'error') and is_err(args[0].error)): work[0] = gen.throw(args[0].error) else: if args[-1] is None: args = args[:-1] if len(args) == 1: work[0] = gen.send(args[0]) else: work[0] = gen.send(args) else: work[0] = gen.next() io_loop.add_callback(execute_work) except StopIteration: if web_handler and not web_handler._finished: web_handler.finish() except Exception, e: if web_handler: if web_handler._headers_written: logging.error('Exception after headers written', exc_info=True) else: web_handler._handle_request_exception(e)
def asynchronous(coroutine): """ Allows a function to not use explicit callback functions to respond to asynchronous events. """ if not isgeneratorfunction(coroutine): # the "coroutine" isn't actually a coroutine; just return # its result like tornado.web.asynchronous would do return coroutine web_async_coroutine = web_async(coroutine) @functools.wraps(coroutine) def run_async_routine(*args, **kwargs): # we check if we're an instancemethod of RequestHandler for better # intergration if len(args) > 0 and isinstance(args[0], RequestHandler): CoroutineRunner(web_async_coroutine(*args, **kwargs), args[0], io_loop) else: CoroutineRunner(coroutine(*args, **kwargs), io_loop=io_loop) return run_async_routine