Skip to content

Instantly share code, notes, and snippets.

@yorickvP
Created November 3, 2012 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yorickvP/4007104 to your computer and use it in GitHub Desktop.
Save yorickvP/4007104 to your computer and use it in GitHub Desktop.
Shut down servers nicely
// keeps track of connections to a http server and closes them when the server closes.
function LinkedList() {
this.start = null
this.end = null }
LinkedList.prototype.add = function(data) {
var ref = { data: data, next: null, prev: null }
if (!this.start) this.start = ref
if (this.end) {
this.end.next = ref
ref.prev = this.end }
this.end = ref
return ref }
LinkedList.prototype.remove = function(ref) {
if (ref == this.start) this.start = ref.next
if (ref == this.end) this.end = ref.prev
if (ref.prev) ref.prev.next = ref.next
if (ref.next) ref.next.prev = ref.prev }
module.exports = function shutdowner(http_server) {
// TODO: detect when it's already wrapped
var old_close = http_server.close
http_server.close = function() {
this.emit('beforeClose')
old_close.apply(this, arguments) }
var conns = new LinkedList()
var closing = false
http_server.on('listening', function() {
http_server.on('connection', function connection_handler(socket) {
var ref = conns.add(socket)
socket.on('close', function() {
conns.remove(ref) })})
http_server.on('request', function(req, res) {
// todo: don't mess with the socket
req.connection._working = true
res.on('finish', function() {
req.connection._working = false
if (closing) req.connection.destroySoon() }) })
http_server.once('beforeClose', function() {
closing = true
for (var conn = conns.start; conn != null; conn = conn.next) {
if (conn && !conn.data._working) conn.data.destroy() }})})}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment