Files
cloudbeaver/webapp/packages/core-executor/src/whileTask.ts
T
2fc9c72908 dbeaver/dbeaver-vscode#77 refactor: yarn & vit migration (#3229)
* dbeaver/vscode#77 refactor: yarn & vit migration

* chore: configure eslint & typescript & prettier

* fix: chunk splitting & assets loading

* fix: enable corepack

* refactor: dev environment

* chore: remove corepack enable from build scripts

* chore: make script executable

* fix: SSL check in vite dev

* chore: update debug launch configs

---------

Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com>
2025-02-05 00:20:23 +08:00

96 lines
2.3 KiB
TypeScript

/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { AutoRunningTask } from './TaskScheduler/AutoRunningTask.js';
import { CancelError } from './TaskScheduler/CancelError.js';
import type { ITask } from './TaskScheduler/ITask.js';
import { Task } from './TaskScheduler/Task.js';
import { TimeoutError } from './TaskScheduler/TimeoutError.js';
export function whileTask<T>(
callback: (value: T) => Promise<boolean> | boolean,
task: () => Promise<T>,
interval: number,
cancelMessage?: string,
timeout?: number,
): ITask<T> {
let resolve: (value: T | PromiseLike<T>) => void;
let reject: (reason?: any) => void;
let fulfilled = false;
let intervalTimeoutId: ReturnType<typeof setTimeout> | null = null;
let timeoutId: ReturnType<typeof setTimeout> | null = null;
let activeTask: Promise<T> | null = null;
let stopped = false;
const lockPromise = new Promise<T>((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
}).finally(() => {
if (intervalTimeoutId !== null) {
clearTimeout(intervalTimeoutId);
}
if (timeoutId !== null) {
clearTimeout(timeoutId);
}
fulfilled = true;
});
function stop() {
if (intervalTimeoutId !== null) {
clearTimeout(intervalTimeoutId);
}
stopped = true;
}
async function cancelTask(exception?: any) {
if (fulfilled) {
return;
}
stop();
if (activeTask instanceof Task) {
await activeTask.cancel();
}
reject(exception);
}
if (timeout !== undefined) {
timeoutId = setTimeout(() => cancelTask(new TimeoutError('Task timeout exceeded')), timeout);
}
function runTask() {
activeTask = task();
activeTask
.finally(() => {
activeTask = null;
})
.then(async value => {
const state = await callback(value);
if (state) {
resolve(value);
} else if (!stopped) {
intervalTimeoutId = setTimeout(runTask, interval);
}
})
.catch(cancelTask);
}
return new AutoRunningTask(
() => {
runTask();
return lockPromise;
},
() => cancelTask(new CancelError(cancelMessage ?? 'Task was cancelled')),
);
}