UNPKG

@webda/core

Version:

Expose API with Lambda

148 lines 4.39 kB
import { v4 as uuidv4 } from "uuid"; import { Core } from "../index.js"; /** * Return a delayer that always wait for the same amount of time * @param pause amount of time to wait * @returns */ export function WaitLinearDelay(pause) { return () => pause; } /** * Return a delayer that always wait for the same amount of time * @param pause amount of time to wait * @returns */ export function WaitExponentialDelay(pause) { return (retries) => Math.pow(2, retries - 1) * pause; } /** * Registry for DelayerFactory */ export class WaitDelayerFactories { /** * Add a delayer * @param type * @param delayer */ static registerFactory(type, delayer) { WaitDelayerFactories.registry[type] = delayer; } /** * Return a registered delayer * @param type * @returns */ static getFactory(type) { return WaitDelayerFactories.registry[type]; } /** * * @param definition to get delayer from * @returns */ static get(definition = { interval: 1000, type: "exponential" }) { return WaitDelayerFactories.getFactory(definition.type)(definition.interval); } } WaitDelayerFactories.registry = { linear: WaitLinearDelay, exponential: WaitExponentialDelay }; /** * Wait for an operation to end * * Some AWS Api require minutes and polling * This method will call the callback function until it returns * `true`, or the max `retries` has been reached. * Between each call, it will wait the `delay` * * If it reaches the max retries without a good answer from * callback, the Promise will be rejected * * @param callback to call between each call * @param retries max number of retries * @param title to display * @param logger logger to use to report * @param delayer function that return pause between each call default to WaitExponential(1000) */ export async function WaitFor(callback, retries, title, logger, delayer) { if (!delayer) { delayer = WaitDelayerFactories.get(); } return new Promise(async (mainResolve, mainReject) => { let tries = 0; let uuid = uuidv4(); if (logger) { logger.logProgressStart(uuid, retries, title); } while (retries > tries++) { if (title && logger) { logger.log("DEBUG", "[" + tries + "/" + retries + "]", title); } if (logger) { logger.logProgressUpdate(tries, uuid); } if (await callback(mainResolve, mainReject)) { if (logger) { logger.logProgressUpdate(retries); } return; } await new Promise(resolve => setTimeout(resolve, delayer(tries))); } mainReject("Timeout while waiting for " + title); }); } /** * Return a promise that can be cancelled */ export class CancelablePromise extends Promise { constructor(callback = () => { // noop }, onCancel = undefined) { let localReject; super((resolve, reject) => { localReject = async () => { if (onCancel) { await onCancel(); } reject("Cancelled"); Core.unregisterInteruptableProcess(this); }; callback(resolve, reject); }); this.cancel = localReject; Core.registerInteruptableProcess(this); } } /** * Create a promise that will loop on the same callback until cancelled */ export class CancelableLoopPromise extends Promise { constructor(callback, onCancel = undefined) { let localReject; let shouldRun = true; super(resolve => { localReject = async () => { if (onCancel) { await onCancel(); } shouldRun = false; Core.unregisterInteruptableProcess(this); }; let loop = () => { if (shouldRun) { return callback(localReject).then(loop); } }; resolve(callback(localReject).then(loop)); }); this.cancel = localReject; Core.registerInteruptableProcess(this); } static get [Symbol.species]() { return Promise; } } //# sourceMappingURL=waiter.js.map