[Web-SIG] Proposed WSGI extensions for asynchronous servers

Christopher Stawarz 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  
> applications.

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  
extensions.

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.


Chris


More information about the Web-SIG mailing list