Rails in Realtime - How LayerVault updates every page in a second
layervault.tumblr.com
layervault.tumblr.com
Big thanks for dropping the link to cache_digests too, not sure how I've managed to miss out on that so far!
Honestly, what you're doing at this point is delaying the big rewrite. That's not a bad thing, but it will still be necessary at some point to offload your real-time features to systems that are intended for those kinds of things from the ground up.
Rails was fundamentally designed to optimize for programmer productivity over speed of execution, with the idea that people generally cost more than hardware. Unfortunately once you get to serious scale the hardware necessary to keep things quick starts costing a lot and operationally it becomes a big headache and stuff just doesn't work.
It's going to take a seismic shift for rails to suddenly outperform lightweight 'real-time' frameworks running on faster scripting languages. We need to be honest and aware of both the benefits as well as the limitations of our tools.
Looks pretty snappy to me.
>Honestly, what you're doing at this point is delaying the big rewrite.
That sounds brilliant! As in:
Layervault in 2012 != Netscape in 1996
Netscape's crufty spaghetti C code != Layervault's elegant but slow Rails codeWanted to point out that you can simplify your "folder count updating" code by using a relatively unused jQuery function: ".load" [1].
$.get($section.attr('data-url'))
.success(function (response) {
$section.html(response);
});
would become $section.load($section.data('url'));
[1] http://jqapi.com/#p=loadRails is used for CRUD operations but Node/Socket.io/Jquery are your 'realtime' framework. Its just simple, proprietary (and not in a bad way) and does exactly the job you need.
We probably will hit a ceiling with Rails (once we decide to take the time to update down from 500ms to 50ms, perhaps) that we might not run into using something built for the job. LayerVault wasn't built to be realtime first and foremost.
No disingenuity intended.
Use observers, pusher, and a client side MVC. Don't serialize records deeply, your client side controller or framework should handle the updates nicely. IMO use `after_commit` http://rails-bestpractices.com/posts/695-use-after_commit . Just let that data flow, brawhlings.
Sure, you can use Sever-Sent-Events, but a Websocket would be sufficient too (and probably works in more places, no less).
Especially since pusher is a third party service and it's probably using
(or is able to use) websockets as a transport for that push anyway?
Pusher.com's page title is "HTML5 WebSocket Powered Realtime Messaging Service", no less.Pusher uses a web socket. Pusher is cheaper when comparing against running our own dumb pub/sub server.
Rails 4 will support SSE, however we're not riding that edge as there were existing solutions to the problem.
-
I think this covers most realtime problems without having to code that much, let alone a secondary server/service to handle the problem, we outsourced it, were happy.
That being said, the day where we need to separate our queueing system will come. But delayed_job/MySQL has brought us much further than I'd thought possible.
How are you integrating Socket.IO with your Rails app? Do you have a separate Node.JS server that is just glossed over in your post, or do you use something like execjs to integrate Socket.IO directly into your Rails app?
Thanks for sharing!