Modify periodic check implementation
parent
d862269f8d
commit
3bf5796cd5
@ -0,0 +1,118 @@
|
|||||||
|
type SimpleFunction<T> = (arg: T) => void;
|
||||||
|
type Return<T> = Promise<T> | T;
|
||||||
|
|
||||||
|
async function toPromise<T>(value: Return<T>): Promise<T> {
|
||||||
|
return value instanceof Promise ? value : Promise.resolve(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a promise which waits until `done` is called or until `timeout` period is reached.
|
||||||
|
* If `timeout` is reached then this will throw an Error.
|
||||||
|
*
|
||||||
|
* @param task The task to wait for.
|
||||||
|
* @param timeout The timeout period.
|
||||||
|
*/
|
||||||
|
export async function waitForTask<T>(
|
||||||
|
task: (done: SimpleFunction<T>) => Return<void>,
|
||||||
|
timeout: number = 2000
|
||||||
|
): Promise<T> {
|
||||||
|
const timeoutPromise = new Promise<T>((_, rej) => {
|
||||||
|
const wait = setTimeout(() => {
|
||||||
|
clearTimeout(wait);
|
||||||
|
rej(new Error('Task timed out.'));
|
||||||
|
}, timeout);
|
||||||
|
});
|
||||||
|
|
||||||
|
const taskPromise = new Promise(async (res, rej) => {
|
||||||
|
try {
|
||||||
|
await toPromise(task(res));
|
||||||
|
} catch (e) {
|
||||||
|
rej(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.race([timeoutPromise, taskPromise]) as Promise<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PollOptions {
|
||||||
|
timeout: number;
|
||||||
|
interval: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a promise which calls the `task` every `interval` until `done` is called or until `timeout` period is reached.
|
||||||
|
* If `timeout` is reached then this will throw an Error.
|
||||||
|
*
|
||||||
|
* @param check The check which runs every `interval` ms.
|
||||||
|
* @param options The polling options.
|
||||||
|
*/
|
||||||
|
export async function poll(
|
||||||
|
task: (done: SimpleFunction<void>) => Return<void>,
|
||||||
|
options: Partial<PollOptions> = {}
|
||||||
|
): Promise<void> {
|
||||||
|
const defaults: PollOptions = {
|
||||||
|
timeout: 2000,
|
||||||
|
interval: 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { timeout, interval } = {
|
||||||
|
...defaults,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
|
const endTime = Date.now() + timeout;
|
||||||
|
let stop = false;
|
||||||
|
const finish = () => {
|
||||||
|
stop = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const _poll = async (resolve: any, reject: any) => {
|
||||||
|
if (stop) {
|
||||||
|
resolve();
|
||||||
|
} else if (Date.now() >= endTime) {
|
||||||
|
finish();
|
||||||
|
reject(new Error('Periodic check timeout'));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
await toPromise(task(finish));
|
||||||
|
} catch (e) {
|
||||||
|
finish();
|
||||||
|
reject(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
void _poll(resolve, reject);
|
||||||
|
}, interval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
void _poll(resolve, reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a promise which waits until `check` returns `true` or rejects if `timeout` preiod is reached.
|
||||||
|
* If `timeout` is reached then this will throw an Error.
|
||||||
|
*
|
||||||
|
* @param check The boolean check.
|
||||||
|
* @param timeout The time before an error is thrown.
|
||||||
|
*/
|
||||||
|
export async function waitUntil(
|
||||||
|
check: () => Return<boolean>,
|
||||||
|
timeout: number = 2000
|
||||||
|
) {
|
||||||
|
// This is causing unhandled promise rejection somewhere in MessageQueue tests
|
||||||
|
return poll(
|
||||||
|
async done => {
|
||||||
|
const result = await toPromise(check());
|
||||||
|
if (result) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timeout,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue