Reading about asyncio in uwsgi at
http://uwsgi-docs.readthedocs.org/en/latest/asyncio.html

I really didn't like the ugly explicit switching, passing the greenlet
around and the future. So I made this simple decorator that hides that
away:

def coroutine(f):

   def _f(*args, **kwargs):
       myself = greenlet.getcurrent()
       co = asyncio.coroutine(f)
       future = asyncio.async(co(*args, **kwargs))

       future.add_done_callback(lambda _: myself.switch()) # goes back
to the suspended call, one line below
       myself.parent.switch()                              # suspends.
goes to the event loop

       return future.result()

   return _f

So it takes the wrapped function, wraps it in a asyncio.coroutine,
sets it for running  as a Task (which returns a future), registers a
callback on the future to switch back the greenlet, and switches away
the greenlet. When the greenlet gets switched back to, it gets the
result of the future and returns that.

@coroutine wrapped functions still need to use 'yield from' of course,
since they are still asyncio coroutines.

Usage is like this:

@coroutine
def sleeping():
   yield from asyncio.sleep(2)
   return b'test'

def application(environ, start_response):
   start_response('200 OK', [('Content-Type','text/html')])
   response = sleeping()
   return [response]


-- 
damjan
_______________________________________________
uWSGI mailing list
[email protected]
http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi

Reply via email to