mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 23:40:45 +00:00
49 lines
1.1 KiB
TypeScript
49 lines
1.1 KiB
TypeScript
export type KeyedAsyncQueueHooks = {
|
|
onEnqueue?: () => void;
|
|
onSettle?: () => void;
|
|
};
|
|
|
|
export function enqueueKeyedTask<T>(params: {
|
|
tails: Map<string, Promise<void>>;
|
|
key: string;
|
|
task: () => Promise<T>;
|
|
hooks?: KeyedAsyncQueueHooks;
|
|
}): Promise<T> {
|
|
params.hooks?.onEnqueue?.();
|
|
const previous = params.tails.get(params.key) ?? Promise.resolve();
|
|
const current = previous
|
|
.catch(() => undefined)
|
|
.then(params.task)
|
|
.finally(() => {
|
|
params.hooks?.onSettle?.();
|
|
});
|
|
const tail = current.then(
|
|
() => undefined,
|
|
() => undefined,
|
|
);
|
|
params.tails.set(params.key, tail);
|
|
void tail.finally(() => {
|
|
if (params.tails.get(params.key) === tail) {
|
|
params.tails.delete(params.key);
|
|
}
|
|
});
|
|
return current;
|
|
}
|
|
|
|
export class KeyedAsyncQueue {
|
|
private readonly tails = new Map<string, Promise<void>>();
|
|
|
|
getTailMapForTesting(): Map<string, Promise<void>> {
|
|
return this.tails;
|
|
}
|
|
|
|
enqueue<T>(key: string, task: () => Promise<T>, hooks?: KeyedAsyncQueueHooks): Promise<T> {
|
|
return enqueueKeyedTask({
|
|
tails: this.tails,
|
|
key,
|
|
task,
|
|
...(hooks ? { hooks } : {}),
|
|
});
|
|
}
|
|
}
|