2026-08-15 18:37:30 +02:00
|
|
|
interface RunHandle {
|
|
|
|
|
runId: string;
|
|
|
|
|
scriptId: string;
|
|
|
|
|
controller: AbortController;
|
|
|
|
|
pid?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
|
var __triggershellRunHandles: Map<string, RunHandle> | undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** In-memory only - live run handles cannot survive a process restart; see `reconcileOrphanedRuns`.
|
|
|
|
|
* Anchored on `globalThis` - see the comment in `runner/events.ts` for why a plain module-level
|
|
|
|
|
* singleton isn't safe here (Next compiles Route Handlers through a separate module graph from
|
|
|
|
|
* what `server.ts` requires directly). */
|
2026-08-16 13:55:25 +02:00
|
|
|
const handles: Map<string, RunHandle> =
|
|
|
|
|
globalThis.__triggershellRunHandles ?? new Map();
|
2026-08-15 18:37:30 +02:00
|
|
|
globalThis.__triggershellRunHandles = handles;
|
|
|
|
|
|
|
|
|
|
export function registerRun(handle: RunHandle) {
|
|
|
|
|
handles.set(handle.runId, handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function unregisterRun(runId: string) {
|
|
|
|
|
handles.delete(runId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRunHandle(runId: string): RunHandle | undefined {
|
|
|
|
|
return handles.get(runId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isRunLive(runId: string): boolean {
|
|
|
|
|
return handles.has(runId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Requests cancellation; returns false if the run isn't tracked (already finished or not this process). */
|
|
|
|
|
export function cancelRun(runId: string): boolean {
|
|
|
|
|
const handle = handles.get(runId);
|
|
|
|
|
if (!handle) return false;
|
|
|
|
|
handle.controller.abort();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function killAllRuns() {
|
|
|
|
|
for (const handle of handles.values()) {
|
|
|
|
|
handle.controller.abort();
|
|
|
|
|
}
|
|
|
|
|
}
|