UNPKG

durable-execution

Version:

A durable task engine for running tasks durably and resiliently

124 lines (121 loc) 3.15 kB
// src/cancel.ts import { getErrorMessage } from "@gpahal/std/errors"; // src/errors.ts import { CustomError } from "ts-custom-error"; var DurableExecutionError = class extends CustomError { /** * Whether the error is retryable. */ isRetryable; /** * @param message - The error message. * @param isRetryable - Whether the error is retryable. */ constructor(message, isRetryable = true) { super(message); this.isRetryable = isRetryable; } getErrorType() { return "generic"; } }; var DurableExecutionCancelledError = class extends DurableExecutionError { /** * @param message - The error message. */ constructor(message) { super(message ?? "Task cancelled", false); } getErrorType() { return "cancelled"; } }; // src/logger.ts function createConsoleLogger(name) { return { debug: (message) => console.debug(`DEBUG [${name}] ${message}`), info: (message) => console.info(`INFO [${name}] ${message}`), error: (message, error) => console.error(`ERROR [${name}] ${message}`, error) }; } // src/cancel.ts function createCancelSignal({ abortSignal, logger } = {}) { logger = logger ?? createConsoleLogger("CancelSignal"); let isCancelled = abortSignal?.aborted ?? false; const subscribers = /* @__PURE__ */ new Set(); const cancel = () => { if (abortSignal) { abortSignal.removeEventListener("abort", cancel); } if (isCancelled) { return; } isCancelled = true; for (const fn of subscribers) { try { fn(); } catch (error) { logger.error(`Error in cancel signal subscriber: ${getErrorMessage(error)}`); } } subscribers.clear(); }; if (abortSignal) { abortSignal.addEventListener("abort", cancel); } const cancelSignal = { onCancelled: (fn) => { if (isCancelled) { fn(); } else { subscribers.add(fn); } }, clearOnCancelled: (fn) => { subscribers.delete(fn); }, isCancelled: () => isCancelled }; return [cancelSignal, cancel]; } function createTimeoutCancelSignal(timeoutMs, { logger } = {}) { const [cancelSignal, cancel] = createCancelSignal({ logger }); setTimeout(() => cancel(), timeoutMs); return cancelSignal; } function createCancellablePromise(promise, signal, cancelledError) { if (!signal) { return promise; } const getCancelledError = () => { if (!cancelledError) { return new DurableExecutionCancelledError(); } if (cancelledError instanceof DurableExecutionError) { return cancelledError; } return new DurableExecutionCancelledError(getErrorMessage(cancelledError)); }; return new Promise((resolve, reject) => { if (signal.isCancelled()) { reject(getCancelledError()); return; } const onCancelled = () => { reject(getCancelledError()); }; signal.onCancelled(onCancelled); promise.then(resolve, reject).finally(() => { signal.clearOnCancelled(onCancelled); }); }); } export { createCancelSignal, createCancellablePromise, createTimeoutCancelSignal }; //# sourceMappingURL=cancel.js.map