[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:
> This specification defines a set of extensions that allow WSGI
> applications to run effectively on asynchronous (aka event driven)
> 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``
> * 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
> 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
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.
More information about the Web-SIG