retry-ts
Version:
Retry combinators for monadic actions that may fail
40 lines (39 loc) • 1.34 kB
JavaScript
/**
* @since 0.1.0
*/
import * as T from 'fp-ts/es6/Task';
import * as O from 'fp-ts/es6/Option';
import { pipe } from 'fp-ts/es6/pipeable';
import { applyPolicy, defaultRetryStatus } from '.';
/**
* Apply policy and delay by its amount if it results in a retry.
* Returns updated status.
*
* @since 0.1.0
*/
export function applyAndDelay(policy, status) {
var newStatus = applyPolicy(policy, status);
return pipe(newStatus.previousDelay, O.fold(function () { return T.task.of(newStatus); }, function (millis) { return T.delay(millis)(T.task.of(newStatus)); }));
}
/**
* Retry combinator for actions that don't raise exceptions, but
* signal in their type the outcome has failed. Examples are the
* `Option`, `Either` and `EitherT` monads.
*
* @since 0.1.0
*/
export function retrying(policy, action, check) {
var go = function (status) {
return pipe(status, action, T.chain(function (a) {
if (check(a)) {
return pipe(applyAndDelay(policy, status), T.chain(function (status) {
return pipe(status.previousDelay, O.fold(function () { return T.task.of(a); }, function () { return go(status); }));
}));
}
else {
return T.task.of(a);
}
}));
};
return go(defaultRetryStatus);
}