Verified Commit 51e6a532 authored by aguestuser's avatar aguestuser

[215] add `util.repeateUntilCancelled`

* calls an async function repeatedly on an interval
* returns a function that, if invoked, cancels the next call of the
  async function
parent 6f0d0966
......@@ -38,6 +38,19 @@ const repeatUntil = (fn, interval, predicate) =>
.then(() => wait(interval))
.then(() => repeatUntil(fn, interval, predicate))
const repeatUntilCancelled = (fn, interval) => {
let shouldContinue = true
const cancel = () => (shouldContinue = false)
const repeat = (fn, interval) =>
!shouldContinue
? Promise.resolve()
: Promise.resolve(fn())
.then(() => wait(interval))
.then(() => repeat(fn, interval))
repeat(fn, interval)
return cancel
}
const repeatUntilTimeout = (fn, interval, timeout) => {
const now = nowInMillis()
repeatUntil(fn, interval, () => nowInMillis() > now + timeout)
......@@ -145,6 +158,7 @@ module.exports = {
redact,
repeatEvery,
repeatUntilTimeout,
repeatUntilCancelled,
sha256Hash,
sequence,
statuses,
......
import { expect } from 'chai'
import { describe, it, beforeEach, afterEach } from 'mocha'
import sinon from 'sinon'
import util from '../../app/util'
describe('utility module', () => {
......@@ -91,4 +92,17 @@ describe('utility module', () => {
})
})
})
describe('#repeatUntilCancelled', () => {
it('calls a function repeatedly until it is cancelled', async () => {
const fn = sinon.stub().returns(Promise.resolve())
const interval = 20
const cancel = util.repeatUntilCancelled(fn, interval)
await util.wait(2 * interval)
expect(fn.callCount).to.eql(2)
cancel()
await util.wait(2 * interval)
expect(fn.callCount).to.eql(2)
})
})
})
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment