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.
_______________________________________________
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