[Web-SIG] Server-side async API implementation sketches

P.J. Eby pje at telecommunity.com
Sun Jan 9 21:56:26 CET 2011


At 08:09 PM 1/9/2011 +0200, Alex Grönholm wrote:
>Asynchronous applications may not be ready to send the status line 
>as the first thing coming out of the generator.

So?  In the sketches that are the subject of this thread, it doesn't 
have to be the first thing.  If the application yields a future 
first, it will be paused...  and so will the middleware.  When this 
line is executed in the middleware:

         status, headers, body = yield app(environ)

...the middleware is paused until the application actually yields its 
response tuple.

Specifically, this yield causes the app iterator to be pushed on the 
Coroutine object's .stack attribute, then iterated.  If the 
application yields a future, the server suspends the whole thing 
until it gets called back, at which point it .send()s the result back 
into the app iterator.

The app iterator then yields its response, which is tagged as a 
return value, so the app is popped off the .stack, and the response 
is sent via .send() into the middleware, which then proceeds as if 
nothing happened in the meantime.  It then yields *its* response, and 
whatever body iterator is given gets put into a second coroutine that 
proceeds similarly.

When the process_response() part of the middleware does a "yield 
body_iter", the body iterator is pushed, and the middleware is paused 
until the body iterator yields a chunk.  If the body yields a future, 
the whole process is suspended and resumed.  The middleware won't be 
resumed until the body yields another chunk, at which point it is 
resumed.  If it yields a chunk of its own, then that's passed up to 
any response-processing middleware further up the stack.

In contrast, middleware based on the 2+body protocol cannot process a 
body without embedding coroutine management into the middleware 
itself.   For example, you can't write a standalone body processor 
function, and reuse it inside of two pieces of middleware, without 
doing a bunch of send()/throw() logic to make it work.


>Outside of the application/middleware you mean? I hope there isn't 
>any more confusion left about what a future is. The fact is that you 
>cannot use synchronous API calls directly from an async app no 
>matter what. Some workaround is always necessary.

Which pretty much kills the whole idea as being a single, universal 
WSGI protocol, since most people don't care about async.



More information about the Web-SIG mailing list