@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
37 lines • 1.85 kB
TypeScript
/**
* Deadline interruption for pyodide, which executes on THIS thread: a
* busy guest loop blocks the event loop, so no timer here can ever
* fire (the quickjs runtime has an in-VM interrupt hook for this;
* pyodide only reads a SharedArrayBuffer via setInterruptBuffer). A
* tiny watchdog worker owns the countdown instead: it writes SIGINT
* (2) into the shared interrupt cell at the deadline, pyodide's
* interpreter loop sees it mid-execution and raises KeyboardInterrupt,
* and the run reports which trip happened through the second cell.
*
* Cells (Int32Array over one SharedArrayBuffer): [0] the pyodide
* interrupt cell (pyodide resets it to 0 when it fires), [1] why the
* trip happened (1 deadline, 2 kill signal), [2] the arm generation,
* which the watchdog re-checks at the deadline so a countdown
* cancelled just as it fires cannot poison the next run. Cell [3]
* records an abort from the host before the worker has armed a run.
*
* Environments without SharedArrayBuffer or workers (a browser page
* that is not cross-origin isolated) get null: runs stay unbounded
* there, exactly the pre-interrupt behavior.
*/
export interface ArmedInterrupt {
/**
* Stop the countdown and report the trip. Idempotent: every later call
* repeats the first answer, so the wrapper can disarm as soon as the
* user code returns and the host can still read why it stopped.
*/
disarm(): 'deadline' | 'signal' | null;
}
export interface PyodideInterrupter {
/** The view to hand to pyodide.setInterruptBuffer, once. */
readonly view: Int32Array;
arm(timeoutSeconds: number | null, signal?: AbortSignal): ArmedInterrupt;
close(): void;
}
export declare function createPyodideInterrupter(buffer?: SharedArrayBuffer): Promise<PyodideInterrupter | null>;
//# sourceMappingURL=interrupt.d.ts.map