The Neuronen Schmiede concerns itself with topics related to software development. One focus are robust web applications.

Loosely Coupled Push Updates


I was not at RailsConf Atlanta and have not watched the DHH keynote. But I did read more than a few Tweets and blog posts about it, or should I say about Action Cable? Action Cable will be part of version five of Ruby on Rails and will integrate push updates via WebSockets. It's not yet available but people are already quite sceptical and I'm one of them. Not of the idea of having push updates via WebSockets. I'm a big fan of push updates and think they are a key component of a good web application. Especially JavaScript applications can benefit a lot by push updates.

Push updates are great, but I'm not sure if it's a good idea to integrate them as tightly with Ruby on Rails as it currently seems. People want to build applications with push updates, like they already build applications with background job processing and sending emails. In my opinion Action Cable should be very similar to Active Job and Action Mailer. There should be a nice interface that allows the programmer to send push updates from within Ruby on Rails.

The actual service that is responsible for delivering the push updates should be outside of Ruby on Rails. This would be very similar to Active Job and Action Mailer. Your application code should not care about these things, it's irrelevant if you are sending emails directly from your server or use a third party service. Push updates should be loosley coupled in the same way, it makes building robust applications easier since it has a few benefits compared to a tightly integrated solution.

Deployment of Ruby on Rails applications does not get more complicated. In most cases it should not be required to touch the push update service when you deploy your application. For example there is already a lot of ill-informed advice when it comes to background processing and deployment. A lot of tutorials and guides encourage you to use something like capistrano/sidekiq. That's not a good idea, managing a service like Sidekiq is the job of the operating system and not of the deployment process of your application. Otherwise your background jobs are not processed after a scheduled server reboot. (Yes I speak from experience. Deploying a non-trivial Ruby on Rails application in a robust way is a topic with surprising little information on the internet so I had to learn by making each and every mistake myself.)

Your application will work without push updates. In a scenario where the push update service gets overwhelmed with connections or something entirely different goes wrong your application will keep running and serving HTTP requests. Granted the user experience will degrade but that's a lot better than having your application server go down due to a problem with push updates.

How could this work? Let's take an Ember.js application with a Ruby on Rails backend as API. The Ember.js frontend communicates with Ruby on Rails via a JSON API as seen in countless examples. There is nothing novel to this approach. As long as the backend is up and running the application is working for our users. Now we can add the push service into the mix, this is a separate program running on the server. Whenever a create, update or destroy action is triggered the backend schedules a push update. Basically it puts the JSON payload into a queue before responding with it to the HTTP request. The push update service takes the payload from the queue and delivers it to all connected WebSocket clients so they receive an immediate update.

Even if the push update service is not working the application itself is not broken. The client is still getting its plain old HTTP response with the payload. The only thing not working is the immediate push update to all other clients.