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.
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.
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.
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.
22 comments
[ 3.9 ms ] story [ 59.7 ms ] threadIt does seem to me like this separation is the right way to handle the problem.
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.
http://www.pocoo.org/team/
https://gist.github.com/8d233bfa42b0d131a19c
Flask and gevent are an excellent combination for realtime web.
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.
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
http://brubeck.io/