[Web-SIG] Proposed WSGI extensions for asynchronous servers

Christopher Stawarz cstawarz at csail.mit.edu
Mon May 12 02:25:57 CEST 2008

On May 11, 2008, at 7:05 PM, Phillip J. Eby wrote:

> At 06:15 PM 5/11/2008 -0400, Christopher Stawarz wrote:
>> Non-blocking Input Stream
>> ~~~~~~~~~~~~~~~~~~~~~~~~~
>> The ``x-wsgiorg.async.input`` variable provides a non-blocking
>> replacement for ``wsgi.input``.  It is an object with one method,
>> ``read(size)``, that behaves like the ``recv`` method of
>> ``socket.socket``.  This means that a call to ``read`` will invoke  
>> the
>> underlying socket ``recv`` **no more than once** and return **at
>> most** ``size`` bytes of data (possibly less).  In addition, ``read``
>> may return an empty string (zero bytes) **only** if the client closes
>> the connection or the application attempts to read more data than is
>> specified by the ``CONTENT_LENGTH`` variable.
>> Before each call to ``read``, the application **must** test the input
>> stream for readiness with ``x-wsgiorg.async.readable`` (see below).
>> The result of calling ``read`` on a non-ready input stream is
>> undefined.
> For this to work, you're going to need this to take the wsgi.input  
> object as a parameter.  If you don't, then this will bypass  
> middleware that replaces wsgi.input.
> That is, you will need a way for this spec to support middleware  
> that's replacing wsgi.input, without the middleware knowing that  
> this specification exists.  In the worst case, it should detect the  
> replaced input and give an error or some response that lets the  
> application know it won't really be able to use the async feature.

I hadn't considered middleware that replaces wsgi.input.  Is there an  
example component you can point me to, just so I have something  
concrete to look at?

Given that the semantics of wsgi.input are, in general, incompatible  
with non-blocking execution, I'm inclined to think that such  
middleware would either need to be rewritten to use x- 
wsgiorg.async.input, or just couldn't be used with asynchronous  
servers.  But I'll think about it some more -- maybe there's a way to  
make this work.

>> If ``timeout`` seconds elapse without the file descriptor becoming
>> ready for I/O, the variable ``x-wsgiorg.async.timeout`` will be true
>> when the application resumes.  Otherwise, it will be false.  The  
>> value
>> of ``x-wsgiorg.async.timeout`` when the application is first started
>> or after it yields each response-body string is undefined.
> Er, I think you are confused here.  There is no way for the server  
> to know what environ dictionary the application is using, unless you  
> explicitly pass it into your extension API.

My thinking is that the server *creates* the environ dictionary, so it  
can just keep a reference to it and update it as needed.  Is  
middleware allowed to replace environ with another dict instance  
before passing it to the application?  I wasn't aware that this was  
allowed, but if it is, then I see the problem.

The solution would probably be for the application to pass a mutable  
object (e.g. an empty list) to readable/writable that the server could  
set a timeout flag on.


More information about the Web-SIG mailing list