mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-01 15:35:12 +01:00
Reviewed and verified at f1c48c924d.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
import type { RunDispatchScope } from "../run-dispatch-notifications.js";
|
|
import type { createDeliveryWorkCoordinator } from "../delivery-work-coordinator.js";
|
|
import { registerDeadlineWork } from "../deadline-work.js";
|
|
import { DELIVERY_QUEUES } from "../delivery-work-notifications.js";
|
|
|
|
export function registerRunDispatchWork(
|
|
coordinator: ReturnType<typeof createDeliveryWorkCoordinator>,
|
|
owner: {
|
|
promoteDueScheduledRetries(): Promise<unknown>;
|
|
nextScheduledRetryAt(): Promise<number | null>;
|
|
resumeQueuedRunsAfterDrain(scope?: RunDispatchScope): Promise<unknown>;
|
|
schedulingSuppressed(): Promise<boolean>;
|
|
},
|
|
canRun: () => boolean,
|
|
) {
|
|
let suppressed = false;
|
|
const retries = registerDeadlineWork(coordinator, DELIVERY_QUEUES.scheduledRetryDispatch, {
|
|
retryMs: 30_000,
|
|
continuationMs: 1_000,
|
|
notificationCoalesceMs: 1_000,
|
|
canRun,
|
|
run: async signal => {
|
|
suppressed = await owner.schedulingSuppressed();
|
|
if (!signal.aborted && !suppressed && canRun()) await owner.promoteDueScheduledRetries();
|
|
},
|
|
next: () => suppressed ? Promise.resolve(null) : owner.nextScheduledRetryAt(),
|
|
});
|
|
const scopes = new Set<string>(["*"]);
|
|
const queue = registerDeadlineWork(coordinator, DELIVERY_QUEUES.queuedRunDispatch, {
|
|
retryMs: 30_000,
|
|
notificationCoalesceMs: 1_000,
|
|
canRun,
|
|
onSettled: hints => { for (const hint of hints ?? ["*"]) scopes.add(hint); },
|
|
run: async signal => {
|
|
const requested = scopes.has("*") ? ["*"] : [...scopes];
|
|
if (requested[0] === "*") scopes.clear();
|
|
else for (const hint of requested) scopes.delete(hint);
|
|
for (let index = 0; index < requested.length; index++) {
|
|
if (signal.aborted || !canRun()) {
|
|
for (const hint of requested.slice(index)) scopes.add(hint);
|
|
return;
|
|
}
|
|
try {
|
|
await owner.resumeQueuedRunsAfterDrain(requested[index] === "*" ? undefined : JSON.parse(requested[index]) as RunDispatchScope);
|
|
} catch (error) {
|
|
for (const hint of requested.slice(index)) scopes.add(hint);
|
|
throw error;
|
|
}
|
|
}
|
|
},
|
|
next: async () => null,
|
|
});
|
|
return {
|
|
ready: Promise.all([retries.ready, queue.ready]),
|
|
wake() { scopes.add("*"); retries.wake(); queue.wake(); },
|
|
async stop() { await Promise.all([retries.stop(), queue.stop()]); },
|
|
};
|
|
}
|