[Web-SIG] Proposed WSGI extensions for asynchronous servers

James Y Knight foom at fuhm.net
Mon May 12 18:18:50 CEST 2008


On May 11, 2008, at 6:15 PM, Christopher Stawarz wrote:
> Abstract
> --------
>
> This specification defines a set of extensions that allow WSGI
> applications to run effectively on asynchronous (aka event driven)
> servers.
>
> Rationale
> ---------
>
> The architecture of an asynchronous server requires all I/O
> operations, including both interprocess and network communication, to
> be non-blocking.  For a WSGI-compliant server, this requirement
> extends to all applications run on the server.  However, the WSGI
> specification does not provide sufficient facilities for an
> application to ensure that its I/O is non-blocking.  Specifically,
> there are two issues:
>
> * The methods provided by the input stream (``environ['wsgi.input']``)
>  follow the semantics of the corresponding methods of the ``file``
>  class.
>
> * WSGI does not provide the application with a mechanism to test
>  arbitrary file descriptors (such as those belonging to sockets or
>  pipes opened by the application) for I/O readiness.

There are other issues. How do you do a DNS lookup? How do you get  
process completion notification? Heck, how do you run a process? Once  
you have I/O readiness information, what do you do with that? I guess  
you'd need to write a whole new asynchronous server framework on top  
of AWSGI? I can't see being able to use it "raw" for any real  
applications.

> The first argument, ``fd``, is either an integer representing a file
> descriptor or an object with a ``fileno`` method that returns such an
> integer.  (In addition, ``fd`` may be ``x-wsgiorg.async.input``, even
> if it lacks a ``fileno`` method.)  The second, optional argument,
> ``timeout``, is either ``None`` or a floating-point value in seconds.
> If omitted, it defaults to ``None``.

What if the event-loop of the server doesn't use integer fds, but  
windows file handles or a java channel object? Where are you allowed  
to get these integers from? Is it always a socket from  
socket.socket().fileno()? Or can it be a file from open().fileno() or  
os.open()? A pipe from os.pipe()? Note that these distinctions are  
important everywhere but UNIX.

> Other Possibilities
> -------------------
>
> * To prevent an application that does blocking I/O from blocking the
>  entire server, an asynchronous server could run each instance of the
>  application in a separate thread.  However, since asynchronous
>  servers achieve high levels of concurrency by expressly *avoiding*
>  multithreading, this technique will almost always be unacceptable.

Well, my claim would be that it's usually acceptable. Certainly  
sometimes it's not, which is where the use of an asynchronous server  
framework comes in handy. But here you're inventing a whole new  
framework...

PS, a minor bug: I notice the spec says wsgiorg.async.input is  
supposed to have only a read function, but you actually call recv() on  
it in the examples.

James


More information about the Web-SIG mailing list