Notify an Ember.js app that a deployment has happened

The approach with refreshing regular web applications after deployment is pretty straightforward, you click on a link, it goes to the server, server renders a page. If the deployment has happened in the meantime, server renders you the current(new) version of the page. The issue with Ember.js is a pretty nice example of how the old approach doesn’t work anymore. You get the whole application when you first request the page, then everything happens in the browser. The only thing that goes between server and the client is the JSON being passed here and there.

Luckily we are already using Sam Saffron’s awesome gem message_bus, to notify the front-end that an update has happened in a model we are working on. So I decided to implement deployment notification using a similar approach.

First, we want to be able for the Ember app to know that a deployment has happened, so registering MessageBus and subscribing it to a channel is the first thing we will do. We chose the ApplicationController for this in Ember, because it is always loaded, regardless of the route. We are using ember-cli-growl component to provide us with growl like notifications, so you might need to adapt the code to suit your needs.

/* global MessageBus */
import Ember from 'ember';

export default Ember.Controller.extend({
  initMessageBus: function() {
   MessageBus.start();
   MessageBus.callbackInterval = 50;
  },
  subscribe: function() {
    var channel = '/deployment';
    var controller = this;
    MessageBus.subscribe(channel, function() {
      controller.growl.info('A new application version has been deployed, please reload the browser page.', { clickToDismiss: true });
    });
  },
  init: function() {
   this._super();
   this.initMessageBus();
   this.subscribe();
  }
});

In Rails, include the message_bus gem in the Gemfile, bundle install and run the console. Now you can try running MessageBus.publish('/deployment', 'foo') and you should see a notification pop up in your ember app. Ok, but we need to be able to call it somehow, and what better way to do it than using Rake.

desc "notifies Ember that a deploy has happened"
task notify_ember: :environment
  MessageBus.publish('/deployment', '')
end

Now you only have to call that task on the server when your deployment has finished and everything will be fine and dandy. There are a lot of options to do this, depending of your deployment strategies, and infrastructure. We are using Capistrano, so a nice after hook, running after the app server has restarted did the job quite well. If you are having trouble setting it up, feel free to ping me in the contact form.

Leave a Reply

Your email address will not be published. Required fields are marked *