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.
_______________________________________________
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe:
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com