Skip to content

Instantly share code, notes, and snippets.

@nulltask
Created February 24, 2012 18:28
Show Gist options
  • Save nulltask/1902783 to your computer and use it in GitHub Desktop.
Save nulltask/1902783 to your computer and use it in GitHub Desktop.
cluster-io
.DS_Store
._*
node_modules/
/**
* Module dependencies.
*/
var express = require('express')
, RedisStore = require('connect-redis')(express)
, cluster = require('cluster');
var app = express()
, server = require('http').createServer(app)
, io = require('./socket')(server);
module.exports = server;
// Configuration
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('basepath', '/');
app.set('port', process.env.PORT || 3000);
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
app.use(express.logger('dev'));
// Routes
app.get('/', function(req, res) {
res.render('index');
});
if (!process.env.NODE_WORKER_ID && !module.parent) {
/**
* Boot.
*/
app.listen(app.get('port'));
console.log("Express server listening on port %d in %s mode", app.get('port'), app.get('env'));
}
!function(window, document) {
var socket = io.connect()
, chart = new SmoothieChart({ grid: { fillStyle: "#fff"}, labels: { fillStyle: "#000" } })
, connection = new TimeSeries();
socket.on('ping', function() {
console.log(arguments);
socket.emit('pong', new Date());
});
socket.on('stat', function() {
console.log(arguments);
connection.append(+new Date(), arguments[0]);
});
window.onload = function(e) {
chart.addTimeSeries(connection, { strokeStyle: 'rgba(69, 183, 244, 1)', fillStyle: 'rgba(255, 255, 255, 1)', lineWidth: 4 });
chart.streamTo(document.getElementById("smoothie"), 500);
};
}(window, document);
/**
* Module dependencies.
*/
var io = require('socket.io-client')
, connected = 0
, host = process.argv[2];
process.nextTick(function() {
var socket = io.connect(host, { 'force new connection': true });
socket.on('connect', function() {
console.log('\t - connected: %s connections', ++connected);
});
process.nextTick(arguments.callee);
});
process.on('uncaughtException', function(e) {
console.log(e);
});
load 'deploy'
Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
load 'config/deploy'
/**
* Module dependencies.
*/
var cluster = require('cluster')
, server = require('./app');
/**
* Set number of worker process.
* Default is number of CPUs.
*/
var workers = process.env.WORKERS || require('os').cpus().length;
/**
* Start cluster.
*/
if (cluster.isMaster) {
/**
* Fork process.
*/
console.log('start cluster with %s workers', workers);
for (var i = 0; i < workers; ++i) {
var worker = cluster.fork();
console.log('worker %s started.', worker.uniqueID);
}
/**
* Restart process.
*/
cluster.on('death', function(worker) {
console.log('worker %s died. restart...', worker.uniqueId);
cluster.fork();
});
} else {
/**
* Start worker.
*/
server.listen(process.env.PORT || 3000);
}
set :ident, "cluster-io"
set :user, "ec2-user"
set :application, "#{ident}"
set :repository, "git://gist.github.com/1902783.git"
set :scm, :git
set :branch, "master"
set :scm_verbose, true
set :deploy_to, "/home/#{user}/app/#{application}"
set :deploy_via, :copy
set :git_shallow_clone, 1
set :workers, 4
set :node_env, 'production'
# benchmarker
role :web, "ec2-46-51-229-142.ap-northeast-1.compute.amazonaws.com"
role :web, "ec2-175-41-203-216.ap-northeast-1.compute.amazonaws.com"
role :web, "ec2-176-34-0-153.ap-northeast-1.compute.amazonaws.com"
role :app, "ec2-176-34-0-153.ap-northeast-1.compute.amazonaws.com"
role :web, "ec2-176-34-32-184.ap-northeast-1.compute.amazonaws.com"
role :app, "ec2-176-34-32-184.ap-northeast-1.compute.amazonaws.com"
role :web, "ec2-175-41-214-57.ap-northeast-1.compute.amazonaws.com"
role :app, "ec2-175-41-214-57.ap-northeast-1.compute.amazonaws.com"
role :web, "ec2-46-51-229-149.ap-northeast-1.compute.amazonaws.com"
role :app, "ec2-46-51-229-149.ap-northeast-1.compute.amazonaws.com"
namespace :deploy do
task :start, :roles => :app do
run "NODE_ENV=#{node_env} WORKERS=#{workers} forever start #{current_path}/cluster.js"
end
task :stop, :roles => :app do
run "forever stop #{current_path}/cluster.js"
end
task :restart, :roles => :app, :except => { :no_release => true } do
run "NODE_ENV=#{node_env} WORKERS=#{workers} forever restart #{current_path}/cluster.js"
end
end
after "deploy:create_symlink", :roles => :app do
run "ln -svf #{shared_path}/node_modules #{current_path}/node_modules"
run "cd #{current_path} && npm install --mongodb:native --production"
end
namespace :prepare do
task :dir do
run "mkdir -p ~/app/#{application}/releases"
run "mkdir -p ~/app/#{application}/shared"
run "mkdir -p ~/app/#{application}/shared/node_modules"
end
task :node do
run "#{try_sudo} yum install git openssl-devel"
run "#{try_sudo} yum groupinstall \"Development Tools\""
run "git clone https://github.com/isaacs/nave.git ~/.nave"
run "#{try_sudo} ~/.nave/nave.sh usemain 0.6.11"
end
end
extend ./layout
block content
h1 Cluster.IO
p See console log.
canvas#smoothie(width='800', height='200')
!!!
html
head
title Cluster.IO
link(rel='stylesheet', href='/stylesheets/style.css')
script(src='//raw.github.com/joewalnes/smoothie/master/smoothie.js')
script(src='/socket.io/socket.io.js')
script(src='/javascripts/app.js')
body
block content
{
"name": "application-name"
, "version": "0.0.1"
, "private": true
, "dependencies": {
"express": "~3.0.6"
, "jade": ">= 0.0.1"
, "socket.io": ">= 0.0.1"
, "socket.io-client": ">= 0.0.1"
, "bouncy": ">= 0.0.1"
, "connect-redis": "1.x"
, "redis": "*"
, "hiredis": "*"
}
}
{
"io": {
"store": "RedisStore"
, "volatile": true
, "redis": {
"host": "localhost"
, "port": 6379
}
}
, "backend": [
["localhost", 3000]
, ["localhost", 3000]
]
}
/**
* Module dependencies.
*/
var bouncy = require('bouncy')
, params = require('./config/params');
/**
* Proxy server.
*/
var proxies = params.backend;
bouncy(function(req, bounce) {
var proxy = proxies[Math.floor(Math.random() * proxies.length)];
bounce(proxy[0], proxy[1]);
console.log('\t - proxy: %s:%s', proxy[0], proxy[1]);
}).listen(8000);
process.on('uncaughtException', function(e) {
console.log(e);
});
console.log('Proxy server listening on port %s', 8000);
/**
* Module dependencies.
*/
var socket = require('socket.io')
, redis = require('redis')
, params = require('./config/params')
, Store = socket[params.io.store];
module.exports = function(server) {
/**
* Listening Socket.IO
*/
var storeOpts = {};
if (Store instanceof socket.RedisStore) {
storeOpts = {
redisPub: redis.createClient(params.io.redis.port, params.io.redis.host)
, redisSub: redis.createClient(params.io.redis.port, params.io.redis.host)
, redisClient: redis.createClient(params.io.redis.port, params.io.redis.host)
}
}
var io = socket.listen(server, {
store: new Store(storeOpts)
});
/**
* Configure Socket.IO
*/
io.configure(function() {
io.set('transports', ['websocket']);
});
/**
* Routes.
*/
io.sockets.on('connection', function(client) {
io.sockets.emit('stat', Object.keys(io.connected).length);
});
return io;
};
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment