- live example is running at http://chat.gevent.org:8088/
- example code at bitbucket
However, using an asynchronous framework requires twisting your code somewhat: because it's all running in the same thread, you cannot simply wait in a view handler until a new message is available, then construct a response and return it to the framework. Instead, you usually return a callback that will be called when a new message is posted to generate the response and thus complete the long polling request. Not a huge obstacle but it does obscure the code flow.
If only we had more light-weight units of execution than threads and processes, implementing ajax apps like this chat would a lot be simpler. Turns out we do, and there are options: Stackless Python and greenlet. The latter is an extension module that runs on a stock Python and that's what gevent currently supports.
The wsgi server bundled with gevent creates a new greenlet for each incoming connection making it's possible in a request handler to sleep, wait for event and even access network without blocking anyone. Greenlets are cheap, memory-wise, so it's about as scalable as callback- or Deferred- based solution. The logic, however, becomes much more transparent:
- When a new message is posted, set the event
- When a client requests the updates (and it already has the latest message), wait for the event