Re: Server-side async API implementation sketches
Alex Grönholm <alex.gronholm-S2Gd0AnZGk/[email protected]>
| Newsgroups | gmane.comp.python.web |
|---|---|
| Message-ID | <[email protected]> |
09.01.2011 05:45, P.J. Eby kirjoitti: > At 06:15 PM 1/8/2011 -0800, Alice BevanMcGregor wrote: >> On 2011-01-08 17:22:44 -0800, Alex Grönholm said: >>>> On 2011-01-08 13:16:52 -0800, P.J. Eby said: >>>> I've written the sketches dealing only with PEP 3148 futures, but >>>> sockets were also proposed, and IMO there should be simple support >>>> for obtaining data from wsgi.input. >>> I'm a bit unclear as to how this will work with async. How do you >>> propose that an asynchronous application receives the request body? >> >> In my example https://gist.github.com/770743 (which has been >> simplified greatly by P.J. Eby in the "Future- and Generator-Based >> Async Idea" thread) for dealing with wsgi.input, I have: >> >> future = >> environ['wsgi.executor'].submit(environ['wsgi.input'].read, 4096) >> yield future >> >> While ugly, if you were doing this, you'd likely: >> >> submit = environ['wsgi.executor'].submit >> input_ = environ['wsgi.input'] >> >> future = yield submit(input_.read, 4096) >> data = future. > > I don't quite understand the above -- in my sketch, the above would be: > > data = yield submit(input._read, 4096) > > It looks like your original sketch wants to call .result() on the > future, whereas in my version, the return value of yielding a future > is the result (or an error is thrown if the result was an error). I cooked up a simple do-nothing middleware example which Alice decorated with some comments: https://gist.github.com/771398 A new feature here is that the application itself yields a (status, headers) tuple and then chunks of the body (or futures). > > > Is there some reason I'm missing, for why you'd want to explicitly > fetch the result in a separate step? > > Meanwhile, thinking about Alex's question, ISTM that if WSGI 2 is > asynchronous, then the wsgi.input object should probably just have > read(), readline() etc. methods that simply return (possibly-mock) > futures. That's *much* better than having to do all that submit() > crud just to read data from wsgi.input(). > > OTOH, if you want to use the cgi module to parse a form POST from the > input, you're going to need to write an async version of it in that > case, or else feed the entire operation to an executor... but then > the methods would need to be synchronous... *argh*. > > I'm starting to not like this idea at all. Alex has actually > pinpointed a very weak spot in the scheme, which is that if wsgi.input > is synchronous, you destroy the asynchrony, but if it's asynchronous, > you can't use it with any normal code that operates on a stream. I liked the idea of having a separate async_read() method in wsgi.input, which would set the underlying socket in nonblocking mode and return a future. The event loop would watch the socket and read data into a buffer and trigger the callback when the given amount of data has been read. Conversely, .read() would set the socket in blocking mode. What kinds of problems would this cause? > > > I don't see any immediate fixes for this problem, so I'll let it > marinate in the back of my mind for a while. This might be the > achilles heel for the whole idea of a low-rent async WSGI. > > _______________________________________________ > Web-SIG mailing list > [email protected] > Web SIG: http://www.python.org/sigs/web-sig > Unsubscribe: > http://mail.python.org/mailman/options/web-sig/alex.gronholm%40nextday.fi _______________________________________________ Web-SIG mailing list [email protected] Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: http://mail.python.org/mailman/options/web-sig/gcpw-web-sig%40m.gmane.org