Last active
January 30, 2017 14:38
-
-
Save marekpiechut/03890e1d40fa17c487406b424843e9ae to your computer and use it in GitHub Desktop.
Simple circuit breaker in ES6 (available in NPM as simple-circuit-breaker)
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
const CLOSED = Symbol('CLOSED') | |
const OPEN = Symbol('OPEN') | |
const HALF_OPEN = Symbol('HALF_OPEN') | |
const MSG = 'Functionality disabled due to previous errors.' | |
module.exports = (asyncFn, gracePeriodMs = 3000, threshold = 1, message = MSG) => { | |
let state = CLOSED | |
let failures = 0 | |
let openedAt | |
function handleSuccess(value) { | |
if(state !== CLOSED) { | |
state = CLOSED | |
failures = 0 | |
} | |
return value | |
} | |
function handleFailure(error) { | |
if(state === HALF_OPEN || state === CLOSED) { | |
failures += 1 | |
if(failures >= threshold) { | |
state = OPEN | |
openedAt = Date.now() | |
} | |
} | |
throw error | |
} | |
function tryReset() { | |
if(state === OPEN && openedAt && Date.now() - openedAt > gracePeriodMs) { | |
state = HALF_OPEN | |
return true | |
} | |
} | |
return function () { | |
if(state === CLOSED || state === HALF_OPEN || tryReset()) { | |
return asyncFn.apply(asyncFn.this, arguments).then(handleSuccess, handleFailure) | |
} else { | |
return Promise.reject(new Error(message)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment