I built Agileista years ago. We use it at Pachube to manage our backlog and iterations. For some time I’ve been meaning to add realtime updates to the task board.
Using the standard pub/sub model I wanted it to work as follows:
We built a socket server at work that follows this pattern using EventMachine and RabbitMQ. This time around I wanted to use Redis and Node.js. Well this is what Alex MacCaw’s rewrite of Juggernaut does. It provides a Ruby interface for publishing messages to Redis. It leverages Socket.IO which selects the transport mechanism your browser supports (WebSockets, Flash, AJAX long polling etc.). You connect to the Node.js server via JavaScript and you publish messages via Ruby.
Follow the Juggernaut README and you’ll be up and running in minutes. I installed Node.js and Redis via homebrew on OS X during development. Here are the steps I took to get that running in production…
Most of this is one off server configuration. Only a few lines of code were required to modify Agileista, thanks to Juggernaut.
I’m running Ubuntu 10.04.
Install Redis
wget http://redis.googlecode.com/files/redis-2.2.2.tar.gz
tar xzvf redis-2.2.2.tar.gz
cd redis-2.2.2
make
sudo make install
Install Node.js
wget http://nodejs.org/dist/node-v0.4.2.tar.gz
tar xzvf node-v0.4.2.tar.gz
cd node-v0.4.2
make
sudo make install
Configure the Redis Server via Upstart
# /etc/init/redis-server.conf
description "redis server"
start on runlevel [23]
stop on shutdown
exec sudo -u rails /path/to/redis-server /path/to/redis.conf
respawn
post-start script
# Make a .pid file for monit
PID=`status redis-server |egrep -oi '([0-9]+)$' |head -n1`
echo $PID > /var/run/redis-server.pid
end script
post-stop script
# Remove the .pid file used by monit
rm -f /var/run/redis-server.pid
end script
Start the Redis server
sudo start redis-server
Configure the Juggernaut server via Upstart
# /etc/init/juggernaut.conf
description "node.js server"
author "lebreeze"
start on runlevel [23]
stop on shutdown
script
# We found $HOME is needed. Without it, we ran into problems
export HOME="/home/rails"
cd /u/apps/juggernaut/current
exec sudo -u rails node server.js >> /var/log/node.log
end script
Start the Juggernaut server
sudo start juggernaut
Publish messages onto Redis from your Ruby app
# TaskBoardController
def update
do_stuff_with(@task)
Juggernaut.publish("task_board_#{@task_board.id}", @task.as_json)
end
Include the necessary JavaScript files in the view
<script src="/javascripts/json.js?1300034527" type="text/javascript"></script>
<script src="/javascripts/socket_io.js?1300034527" type="text/javascript"></script>
<script src="/javascripts/juggernaut.js?1300034527" type="text/javascript"></script>
Connect to the server
var log = function(data){
// notify
};
var update = function(data){
// update the taskboard
};
var jug = new Juggernaut({secure: ('https:' == document.location.protocol)});
jug.on("connect", function(){ log("Connected") });
jug.on("disconnect", function(){ log("Disconnected") });
jug.on("reconnect", function(){ log("Reconnecting") });
jug.subscribe("task_board_NN", function(data){
update(data);
});
Monitor Redis and Juggernaut server via monit (extra credit)
sudo vim /etc/monit/monitrc
# monitrc
check process redis with pidfile /var/run/redis-server.pid
start program = "/sbin/start redis-server"
stop program = "/sbin/stop redis-server"
if failed host 127.0.0.1 port 6379 then restart
if 5 restarts within 5 cycles then timeout
check host nodejs with address 127.0.0.1
start program = "/sbin/start juggernaut"
stop program = "/sbin/stop juggernaut"
if failed port 8080 protocol HTTP
request /
with timeout 10 seconds
then restart
# end monitrc
Levent Ali · 13 March 2011 · node.js ruby juggernaut rails monit redis rabbitmq eventmachine ubuntu