@webda/core
Version:
Expose API with Lambda
148 lines • 4.39 kB
JavaScript
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