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

Alex Grönholm alex.gronholm at nextday.fi
Sun Jan 9 22:15:41 CET 2011


09.01.2011 22:56, P.J. Eby kirjoitti:
> 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.
Some boilerplate code was necessary in WSGI 1 middleware too. Alice's 
cleaned up example didn't look too bad, and it would not require that 
Coroutine stack at all.

I think that at this point both sides need to present some code that 
really works, and those implementations could then be compared. The 
examples so far have been a bit too abstract to be fairly evaluated.
>
>
>> 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.
I'm confused. Did you not know this? If so, why then were you at least 
initially receptive to the idea?
Personally I don't think that this is a big problem. Async apps will 
always have to take care not to block the reactor unreasonably long, and 
that is never going to change. Synchronous apps just need to follow the 
protocol, but beyond that they shouldn't have to care about the async 
side of things.
>
>



More information about the Web-SIG mailing list