Skip to content

Instantly share code, notes, and snippets.

@fxg42
Last active February 19, 2017 23:04
Show Gist options
  • Save fxg42/a63deb0958b6b2333ae1d3c41331efe8 to your computer and use it in GitHub Desktop.
Save fxg42/a63deb0958b6b2333ae1d3c41331efe8 to your computer and use it in GitHub Desktop.
CircuitBreaker with Promises
const handleResolve = (breaker) => (value) => {
breaker.state = closed
breaker.errorCount = 0
return Promise.resolve(value)
}
const handleReject = (breaker) => (reason) => {
breaker.errorCount += 1
breaker.state = (breaker.errorCount >= breaker.maxErrorCount ? opened : closed)
if (breaker.state === opened) setTimeout(() => breaker.state = halfOpened, breaker.resetTimeout)
return Promise.reject(reason)
}
const closed = (breaker, argsList) => {
const timeoutPromise = new Promise((resolve, reject) => setTimeout(() => reject('timeout'), breaker.callTimeout))
return Promise.race([ timeoutPromise, breaker.f(...argsList) ]).then(handleResolve(breaker)).catch(handleReject(breaker))
}
const halfOpened = (breaker, argsList) => {
breaker.state = opened
return closed(breaker, argsList)
}
const opened = (breaker, argsList) => {
return Promise.reject('breaker_opened')
}
export const protect = (f, { maxErrorCount=5, resetTimeout=1000, callTimeout=5000 } = {}) => {
const breaker = { f, maxErrorCount, resetTimeout, callTimeout, errorCount: 0, state: closed }
return (...argsList) => breaker.state(breaker, argsList)
}
/*
const resolvesFast = (x) => Promise.resolve(x)
const rejectsFast = (x) => Promise.reject(x)
const resolvesSlow = (x) => new Promise((resolve, reject) => setTimeout(() => resolve(x), 5000))
const rejectsSlow = (x) => new Promise((resolve, reject) => setTimeout(() => reject(x), 5000))
const main = async (fn) => {
try {
const value = await fn(1)
console.log('value', value)
} catch (reason) {
console.log('reason', reason)
}
}
main(protect(resolvesSlow, { callTimeout:1000 }))
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment