Send message to all workers with cluster2

We've been using the cluster2 library to setup a simple cluster for our Node servers, creating one process for each CPU on the server. Although
it has a few rough edges, such as a weird but apparently harmless startup error, it seems to work well, and halved the average response time when benchmarking.
Of course, when using a cluster, sometimes you need to be able to communicate between all the workers. It turns out this is actually pretty easy, since cluster2
is build on top of Node's inbuilt cluster library, we can just use the in-built messaging events to communicate between workers.

Listening to messages in our workers

cluster2 has inbuilt message handling in the master process. If we send a message object with a command key, it will send this message to every worker in the cluster. This isn't a documented feature, so it might be changed in the future, but right now it makes sending messages to workers pretty easy. You can see the code in process.js:

worker.on('message', function(message) {
    if(message && message.command) {
        self.notifyWorkers(message);
    }
});

Notify workers just loops through all the workers and messages them:

this.notifyWorkers = function(message) {
    _.each(self.workers, function(worker) {
        worker.send(message)
    });
}

In our workers we just need to implement an event handler, for example in our Zappa projects we just put something like this in our app setup code:

process.on("message", (msg) ->
    if msg.command is 'doSomething'
        console.log("I am about to do #{msg.action}")
)

All node code can access the process object in global scope, so you don't need to require anything to access that: simple.

Sending a message to all workers

Sending a message to all workers is then a piece of piss. For example we could write a controller action like this:

@get '/say/:something' : ->
    process.send({command: 'doSomething', action: @params.something})

So if we perform a GET to /say/funkymonkey each worker will get a message object looking like:

{command: 'doSomething', action: 'funkymonkey'}