Issue - https://tracker.exphosted.com/view.php?id=7931
As phase (1) we will keep juggernaut and scale up the chat. Some time in future, we will move to XMPP based chat completely.
Continuing from here - https://wiki.exphosted.com/doku.php/chat_implementation#upgrading_chat_server_to_latest_version
We need to upgrade to later versions of socket.io to handle mutliple issues with connections. But macman/juggernaut repo is depricated and is not being maintained now. So, we did a bit of research and see that we should go with GroupSite/juggernaut - https://github.com/Groupsite/juggernaut
This is forked here - https://github.com/udayakiran/juggernaut and will be maintained from here after.
1. Install node https://nodejs.org/en/blog/release/v0.10.40/
2. Clone or down load the repo to a directory say “juggernaut”
git clone https://github.com/udayakiran/juggernaut juggernaut
3. Setup juggernaut -
cd juggernaut npm install
4. Download latest version of redis (3.0.5) and extract it.
5. Start redis and juggernaut
cd redis_src_dir ./redis-server cd juggernaut node server.js #nodejs server.js on Ubuntu
Change the app/views/layouts/_bottom_scripts_and_styles.html.haml to remove the older juggernaut files and include the line below.
%script{:type => "text/javascript", :src => "#{chat_server_url}/application.js", :charset => "utf-8"}
Now run the app and you should see from the logs that channels get the messages but they do not deliver in the UI.
With this clone of juggernaut socket io is upgraded to 0.9.9 and application.js code suggessts that the way we handle channels is changed. This needs to be fixed and other changes need to be done so that chat works fine.
This is important to scale up the chat. Right now we send ajax requests to a metal end point periodically and set users as online. This is causing huge load on app servers. This needs to happen though a push mechanism of juggernaut.
Reference - https://github.com/Groupsite/juggernaut ('Building a roster' section)
http://www.ryanepp.com/blog/how-do-i-tell-if-a-user-is-online
1. We need to show list of online users in a learning site and the groups associated.
2. Store the online users in redis. User may login from multiple tabs. So, a count is maintained to indicate the user logged in status. This counter is incremented on juggernaut connect callback and is decremented on juggernaut disconnect callback. When this count is 0, user is offline.
3. When a user record is active in redis, it should include user displayname , profile image url and groups details are stored as well. No DB queries are to be run when online user details are fetched. When ever data gets updated, juggernaut event is fired to the relavant channels and the changes are pushed.
4. Need to write additional juggernaut callbacks on client to handle user coming online and going offline.
5. Also, care needs to be taken that in case redis goes down, or data is lost, it is handled gracefully.
1. Install node https://nodejs.org/en/blog/release/v0.10.40/
cd /usr/local/ wget https://nodejs.org/dist/v0.10.40/node-v0.10.40-linux-x64.tar.gz tar --strip-components 1 -xzf node-v0.10.40-linux-x64.tar.gz
2. Clone or down load the repo to a directory say “juggernaut”
git clone https://github.com/udayakiran/juggernaut juggernaut
3. Setup juggernaut -
cd juggernaut npm install
4. Download latest version of redis (3.0.5) and extract it.
cd /home/expdev01/apps/chat wget http://download.redis.io/releases/redis-3.0.5.tar.gz tar xvf redis-3.0.5.tar.gz cd redis-3.0.5 make cp redis.conf src/
5. Start redis and juggernaut
modify the script, and then start using ./chat_sss.sh start|stop
#!/bin/bash
JUGDIR="/home/expdev01/apps/chat/juggernaut"
REDISDIR="/home/expdev01/apps/chat/redis-3.0.5/src/"
start()
{
if (status)
then
echo Either redis or node server or both are running, please stop and start again...
else
[ ! -d ${JUGDIR} -o ! -d ${REDISDIR} ] && { echo Required folders not present; exit 1; }
cd ${REDISDIR}
echo Starting redis server..
./redis-server redis.conf >>/dev/null &
cd ${JUGDIR}
rm -f nohup.out
echo Starting node server.js...
at now <<-EOF
nohup node server.js --port 8091 > /var/log/chat.log &
EOF
fi
}
stop()
{
echo Stopping node server.js...
pkill -15 node
sleep 2
echo Stopping redis server..
pkill -15 redis-server
}
status()
{
ps -eo cmd |grep "[n]ode server.js" > /dev/null 2>&1
NODESTATUS=$?
ps -eo cmd |grep [r]edis-server > /dev/null 2>&1
REDISSTATUS=$?
if [ ${NODESTATUS} -eq 0 -o ${REDISSTATUS} -eq 0 ]
then
ps -ef |grep "[n]ode server.js"
ps -ef |grep [r]edis-server
return 0
else
return 1
fi
}
case $1 in
start) start;;
stop) stop;;
status) status;;
restart)
:
stop
start
;;
*) echo Usage $0 start stop status ... ;;
esac
5. Adding roster god script
a. Go to https://repos.exphosted.com/svnrepos/crossbow/trunk/config/god/generic_monitoring.rb, copy the roster stanza from the svn and add it to the end of the /deploy/crossbow/shared/config/god/generic_monitoring.rb
b. edit /deploy/crossbow/shared/config/development.god, and the line under PROCESS_SETTINGS hash;
:roster => {:cpu => 80.percent, :memory => 900.megabytes }
c. Edit /deploy/systaks/god.sh and make sure the WATCHES includes roster;
WATCHES="memcached office xvfb rufus delayed_job roster"