[Web-SIG] Proposed WSGI extensions for asynchronous servers
cstawarz at csail.mit.edu
Mon May 12 20:55:27 CEST 2008
On May 12, 2008, at 12:18 PM, James Y Knight wrote:
> 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?
These are valid questions that I'm not attempting to address with this
proposal. So maybe the title of my spec should be "Extensions for
Asynchronous I/O", since that's the only issue it deals with. I see
these other issues as something for other specifications to address.
> 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
No, you don't need a whole new framework. You need libraries (for
making HTTP requests, talking to databases, etc.) that are written to
use the extensions the spec provides. These only need to be written
once and can then be used with *any* server that supports the
So the existence of a spec like this lets us move from a world where
every server/framework (be it Twisted, nginx, cogen, whatever) needs
to reimplement these utilities in terms of its own async I/O
framework, to one where a single implementation can be written against
the spec and then used by any server that implements it. In turn,
this should make application developers more comfortable with
targeting their apps at async servers, since they won't be tied to any
particular server/framework's API.
And, yes, the fact that what I just wrote sounds like "write once, run
anywhere" sets off alarm bells in my head, too :) But I think the
interface I propose is so basic that any async server should be able
to provide it with very little trouble.
> 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.
Although I didn't state it in the spec, my thinking was that readable/
writable should accept whatever would be accepted by select() on the
platform you're running on. On Windows, they would be limited to
sockets; elsewhere, any file descriptor would do.
In that light, maybe the title should really be "Extensions for
Polling File Descriptors for I/O Readiness". But even limited to that
scope, I still think it'd be extremely useful.
>> * 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.
I don't get how it's acceptable. If you spawn a separate thread for
each request, then your server is no longer asynchronous. At that
point, why not just save yourself some trouble and use Apache?
> 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.
Thanks. The examples in the spec text are correct, but I haven't
updated the examples in my reference code yet.
More information about the Web-SIG