[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 Bevan­McGregor 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