Skip to content

Instantly share code, notes, and snippets.

@aadityabhatia
Created October 10, 2012 22:40
Show Gist options
  • Select an option

  • Save aadityabhatia/3868983 to your computer and use it in GitHub Desktop.

Select an option

Save aadityabhatia/3868983 to your computer and use it in GitHub Desktop.
node.js HTTP Proxy Cluster
cluster = require 'cluster'
if not cluster.isMaster then return require 'webapp2'
PORT = process.env.PORT or 8000
process.env.PORT = 0
httpProxy = require 'http-proxy'
util = require 'util'
express = require 'express'
gitpull = require 'gitpull'
gitsha = require 'gitsha'
require 'colors'
util.log "Initializing HTTP Proxy Cluster...".green.bold
numCPUs = require('os').cpus().length
forkCount = 0
forkTokenCount = numCPUs
setInterval (-> forkTokenCount++ unless forkTokenCount >= numCPUs * 2), 1200000
cluster.fork() for i in [0...numCPUs]
cluster.on 'fork', -> forkCount++
cluster.on 'exit', (worker, code, signal) ->
forkCount--
if worker.suicide
util.log "Worker killed: pid: #{worker.process.pid}, code #{code}, signal #{signal}"
else
util.log "Worker died: pid: #{worker.process.pid}, code #{code}, signal #{signal}".red
if forkTokenCount > 0
forkTokenCount--
util.log "Forking again. Tokens left: #{forkTokenCount}".yellow
setTimeout (-> cluster.fork()), 1000
else
util.log "Too many crashes. Giving up.".red
util.log "Forks left: #{forkCount}".yellow
if not forkCount then process.exit(2)
proxyPorts = []
cluster.on 'listening', (worker, address) ->
if address.port is 0
util.error "Unable to detect worker's listening port; requires node 0.9.3 or newer."
process.exit 3
if PORT in proxyPorts then return
httpProxy.createServer(address.port, 'localhost').listen PORT, ->
util.log "Proxy listening at http://localhost:#{PORT}/"
proxyPorts.push PORT
controller = express.createServer()
controller.post '/update', (req, res) ->
gitsha __dirname, (error, output) ->
if error then return util.error output
initChecksum = output
util.log "gitpull'ing...".cyan
util.log "initial checksum: #{output}"
gitpull '.', (error, output) ->
if error then return util.error output
util.log "gitpull success"
gitsha __dirname, (error, output) ->
if error then return util.error output
util.log "final checksum: #{output}"
if output is initChecksum
return util.log "No updates found!".red
util.log "Update found, restarting workers!".green
worker.disconnect() for id, worker of cluster.workers
cluster.fork() for i in [0...numCPUs]
res.send 'roger'
controller.get '*', (req, res) ->
res.send '404 Not Found', 404
controller.post '*', (req, res) ->
res.send '404 Not Found', 404
controller.listen process.env.CONTROLLER_PORT or 0, ->
addr = controller.address().address
port = controller.address().port
util.log "[#{process.pid}] Controller: http://#{addr}:#{port}/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment