The original post can be found at http://blog.izs.me/post/65712662830/restart-nodejs-servers-on-domain-errors-sensible
Last active
February 18, 2016 11:26
-
-
Save spion/8517936 to your computer and use it in GitHub Desktop.
Shank shiz without crashing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A generic library that can be used to | |
// acquire resources which may get into | |
// an unusable state if something throws | |
// while they're being used. | |
var Promise = require('bluebird'); | |
// Acquires an acquirable resource, then passes it to | |
// the function fn, returning its returned result. | |
// If fn throws, the resource is disposed and will be | |
// recreated the next time its acquired | |
function acquire(res, fn) { | |
return res._get() | |
.then(fn) | |
.catch(function(e) { | |
var p = res._get(); | |
return p.bind(res) | |
.then(res._disposer) | |
.finally(res._nullify) | |
.finally(function() { | |
throw e; | |
}); | |
}); | |
} | |
// Creates a resource which may be acquired. Pass | |
// a factory function (lambda) that takes no arguments. | |
// If the resource contains file handles, also pass | |
// a dispose function that gets rid of them. | |
acquire.create = function create(fn, dispose) { | |
return new Acquirable(fn, dispose); | |
} | |
function nothing() {} | |
function Acquirable(fn, dispose) { | |
this._factory = fn; | |
this._disposer = dispose || nothing; | |
this._instance = null; | |
} | |
Acquirable.prototype._get = function Acquirable$_get() { | |
if (this._instance == null) { | |
this._instance = Promise.try(this._factory); | |
} | |
return this._instance; | |
} | |
Acquirable.prototype._nullify = function Acquirable$_nullify() { | |
this._instance = null; | |
} | |
module.exports = acquire; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Using acquire.js we can safely use the shiz | |
// library even though its throws cause the | |
// shiz object to get into an bad state | |
var shizer = require('./shiz'); | |
var acquire = require('./acquire'); | |
var shiz = acquire.create(function() { return shizer(); }); | |
function doSomeShiz(n) { | |
return acquire(shiz, function(shiz) { | |
shiz.expect(n); | |
for (var i = 0; i < n; i++) { | |
shiz(); | |
} | |
}); | |
} | |
setInterval(function() { | |
doSomeShiz(10); | |
}, 1000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Some bug in the code causes it to crash sometimes. | |
// Gee, that sure is annoying! Server restarts in a | |
// clean state, and spams the error log until we go | |
// in and fix it. | |
// <spion> The only refactoring I did to this function | |
// is to make the state non-global. Most modules | |
// export a (factory) function anyway so usually that | |
// wont be a problem | |
module.exports = function shiz() { | |
// this is some internal state etc. | |
var theShiz = 0; | |
var expectShiz = 0; | |
console.log("Making new shiz"); | |
function expect(n) { | |
expectShiz = n; | |
theShiz = 0; | |
} | |
function verify() { | |
console.log('did %d of shiz, expected %d', theShiz, expectShiz); | |
console.log('cleanup shiz'); | |
theShiz = 0; | |
} | |
function shiz() { | |
theShiz++; | |
// oops | |
// such error | |
// many throw uncawt lul | |
if (Math.random() > 0.5) | |
throw new Error('shank shiz'); | |
if (theShiz === expectShiz) | |
verify(); | |
if (theShiz > expectShiz) | |
throw new Error('uh o so error such unexpect'); | |
} | |
shiz.verify = verify; | |
shiz.expect = expect; | |
return shiz; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment