Skip to content

Instantly share code, notes, and snippets.

@clifton
Created June 20, 2011 04:49
Show Gist options
  • Save clifton/1035144 to your computer and use it in GitHub Desktop.
Save clifton/1035144 to your computer and use it in GitHub Desktop.
fe1 localhost:3000
fe2 127.0.0.1:3000
fe3 0.0.0.0:3000
fs = require 'fs'
http = require 'http'
{EventEmitter} = require 'events'
path = require 'path'
colors = require 'colors'
hostsDir = path.join __dirname, '../hosts'
class HostList extends EventEmitter
constructor: (@group) ->
[self, @servers, @queue] = [this, {}, []]
@path = path.join __dirname, '../hosts', @group
@update()
setInterval (-> self.healthCheck()), 500
fs.watchFile @path, (err, stats) ->
return if self.mtime < stats.mtime
self.mtime = stats.mtime
self.update()
update: ->
[old, @servers, @queue] = [@servers, {}, []]
for line in fs.readFileSync(@path).toString().split(/\r?\n/)
if line
if ([name, host] = line.split ' ').length == 2 and !old[name]?
@log 'NEW', name
@servers[name] = host
log: (action, name) ->
console.log "#{action.red}: #{@group.yellow} #{name}"
get: ->
return unless @queue.length > 0
target = @queue.shift()
[host, port] = target.split(':')
@queue.push(target)
{host: host, port: port}
healthCheck: ->
self = this
down = (name, url) ->
if url in self.queue
self.log 'DOWN', name
self.queue.splice self.queue.indexOf(url), 1
up = (name, url) ->
if url not in self.queue
self.log 'UP', name
self.queue.push url
for name, url of @servers
do (url, name) ->
[host, port] = url.split ':'
http.get({host: host, port: port, path: '/health-check'},
(res) ->
if res.statusCode == 200
up name, url
else
down name, url
).on('error', (err) -> down name, url)
exports.HostList = HostList
live1 0.0.0.0:8082
node1 0.0.0.0:8100
http = require 'http'
{HttpProxy} = require 'http-proxy'
proxy = new HttpProxy
{HostList} = require './lib/host-list'
backends = {}
server = http.createServer (req, res) ->
target = backends[route req].get()
proxy.proxyRequest req, res, target
server.on 'upgrade', (req, socket, head) ->
target = backends[route req].get()
proxy.proxyWebSocketRequest req, socket, head, target
server.listen 8000
route = (req) ->
_route = req.url.match /^\/([\w]+)/
if req.upgrade
'live'
else if _route and backends[_route[1]]?
_route[1]
else
'frontends'
for group in ['live', 'frontends', 'node']
backends[group] = new HostList group
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment