[Web-SIG] Server-side async API implementation sketches
Alex Grönholm
alex.gronholm at nextday.fi
Sun Jan 9 05:06:19 CET 2011
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
> Web-SIG at python.org
> Web SIG: http://www.python.org/sigs/web-sig
> Unsubscribe:
> http://mail.python.org/mailman/options/web-sig/alex.gronholm%40nextday.fi
More information about the Web-SIG
mailing list