[Web-SIG] Proposed WSGI extensions for asynchronous servers
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
>> 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
> 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
>> 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