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

Reply via email to