22 comments

[ 3.9 ms ] story [ 59.7 ms ] thread
Doesn't Mongrel2 operate this way? The front-end handles the open connections, and the backend can choose to send data to any connection. (I have no first-hand experience with Mongrel2, so someone correct me if I'm wrong.)

It does seem to me like this separation is the right way to handle the problem.

This is an excellent article--if you aren't familiar with Armin's writing, you should read all his stuff, he always writes insightful long-form posts which do a tremendous job of making complex topics understandable.

I'd like to just point out that in regards to this article, the whole pub-sub pattern for handling realtime web applications applies not only to python, but to all languages and frameworks. Putting your core application logic behind a pubsub channel is an excellent way to maintain a stateless architecture for large applications while keeping complexity low.

It applies especially well to Python (and MRI Ruby and many others) that aren't capable of holding open connections. There are more options in other languages and frameworks. Lift does real-time without Redis (using the an OS thread per active connection in a container with continuations). Haskell (async run-time is transparent) can easily hold open thousands of idle connections.
Saying that "Python and [...] aren't capable of holding open connections" is just plain wrong. There are many solutions for that, the obvious one for Python being Twisted.
There are plently of ways of holding connections open using Python. Twisted, Gevent, and other connection pools have all solved this problem. Though, some of them are not quite as elegant as Haskell's approach.
Thanks for qualifying that statement for me. Also, there is the multi-core issue for Python & MRI Ruby (leading to memory bloat).
It's worth noting that Flask can be upgraded to a "realtime framework" using like 5 lines of code and a WSGI server that supports websocket.

https://gist.github.com/8d233bfa42b0d131a19c

Flask and gevent are an excellent combination for realtime web.

I feel like I have to rethink the way I've been doing applications for the last 10 years. This is such an obvious approach yet so easy to overlook when you're used to "thinking inside the box" of web application frameworks.

There's obviously times where this approach makes no sense. But for any large application that involves both realtime sockets as well as traditional HTTP requests it's a great way to make things easier on yourself down the road. No need to have a separate codebase or server for your realtime application.

(comment deleted)
This is the same way I implemented Instabot[1] with. Instabot is an IRC/etc bot for teams, so I didn't want connections to irc to be reset every time we upgraded the server code.

I agree that this is the obvious way to do it. Each client has an id, it talks to the backend via a Redis queue and all the state is in the database, which the irc client never sees.

The irc client itself is written in Go, which means that we should really only ever need that one process for all the irc clients. If anyone wants more info I can write it up quickly.

[1] http://instabot.stochastictechnologies.com

Please do write it up if you can, I'm interested. Thanks!
Fantastic, I will. It was my first foray into Go, too, so I might do a writeup on that too (spoiler: I quite liked Go).
What happened to realtime meaning "guaranteed time to success or failure"?
Context matters. Words can have different meanings in different contexts.
The web community needed a word and that one was chosen I guess. I am more than happy to change the post to refer to the thing with a different name but I could not find one.
I believe a more formal definition of realtime is: When missing a deadline constitutes a system failure. Given this definition realtime systems are not bucketed in such a way that they invite a false dichotomy. For instance on one end of the spectrum you would have hard realtime systems (e.g. a pacemakers) where missing a deadline means death of the patient or serious financial loss. On the other end of the spectrum you would have soft realtime systems (e.g. facebook) where missing a deadline of say displaying a web page in under a second would constitute a system failure (revenue/engagement decrease), but still be valuable (people will put up with slow page loads, look at reddit).
I feel like it should be possible to host a server which will hold incoming sockets which proxies back to HTTP, thereby making a bolt-on solution for real-time. Then again, maybe I'm just describing a webserver. :-/
I searched around but couldn't understand what this means: 'Many applications (and all Flask applications by default) will even used cookies with a MAC to store your session information so that you can pass state between independent workers without requiring a single database operation.' <-- what is MAC and how is it used?
Isn't this also how Mongrel2 works? Using ZeroMQ you can have the client keep the connection open as long as you want, and your back-end workers can send data over ZeroMQ as much as they want, and they are not stuck processing at all, they can disappear or be restarted as you please and then resume sending.
This is my understanding, as well. There's a Python framework that builds on top of that, too:

http://brubeck.io/