dce-mango
Version:
Harvard DCE's Non-relational DB Wrapper.
55 lines (48 loc) • 1.47 kB
text/typescript
// Import from NodeJS
import * as timers from 'timers/promises';
export class PollingError extends Error {
public constructor(message?: string) {
super(message);
this.name = 'PollingError';
// See SO post: https://stackoverflow.com/a/48342359
// restore prototype chain
const actualProto = new.target.prototype;
Object.setPrototypeOf(this, actualProto);
}
}
/**
* Function for polling a given resource.
* @author Benedikt Arnarsson
* @param opts.callResource the function for calling the external resource
* @param opts.validateResult validate that we got the result we want from the resource
* @param opts.waitForMS time between calls to the resource (in milliseconds)
* @param opts.maxAttempts the maximum number of attempts (defaults to 'infinity')
*/
const pollResource = async <T>(
opts: {
callResource: () => Promise<T>,
validateResult: (res: T) => boolean,
waitForMS: number,
timeOut?: number,
},
) => {
const {
callResource,
validateResult,
waitForMS,
timeOut,
} = opts;
for (let t = 0; t <= timeOut; t += waitForMS) {
const result = await callResource();
if (validateResult(result)) {
return result;
}
await timers.setTimeout(waitForMS);
}
// FIXME: better error message?
throw new PollingError(`Exceeded timeout of ${timeOut}.
With wait interval of ${waitForMS}.
With polling function:
${callResource.toString()}`);
};
export default pollResource;