chore(vendor): import pi 0.85.1
Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
This commit is contained in:
64
third_party/pi/packages/agent/src/harness/execution/effect-gate.ts
vendored
Normal file
64
third_party/pi/packages/agent/src/harness/execution/effect-gate.ts
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/** Expected internal control flow when cancellation wins effect admission. */
|
||||
export class AbortRequested extends Error {
|
||||
readonly cancellation: Promise<void>;
|
||||
|
||||
constructor(cancellation: Promise<void>) {
|
||||
super("Abort requested");
|
||||
this.name = "AbortRequested";
|
||||
this.cancellation = cancellation;
|
||||
}
|
||||
}
|
||||
|
||||
/** Procedure-facing synchronous admission capability for one drive pass. */
|
||||
export interface Gate {
|
||||
readonly signal: AbortSignal;
|
||||
admit<T>(invoke: () => T): T;
|
||||
}
|
||||
|
||||
/** Owner-facing lifecycle controls for one drive pass. */
|
||||
export interface GateControl {
|
||||
beginAbort(cancellation: Promise<void>): void;
|
||||
signalAbort(): void;
|
||||
close(error: Error): void;
|
||||
}
|
||||
|
||||
type GateState =
|
||||
| { status: "open" }
|
||||
| { status: "aborting"; cancellation: Promise<void> }
|
||||
| { status: "closed"; error: Error };
|
||||
|
||||
/** Create separate procedure-facing and owner-facing views of one effect gate. */
|
||||
export function createGate(): { gate: Gate; control: GateControl } {
|
||||
let state: GateState = { status: "open" };
|
||||
const controller = new AbortController();
|
||||
|
||||
const check = (): void => {
|
||||
if (state.status === "aborting") throw new AbortRequested(state.cancellation);
|
||||
if (state.status === "closed") throw state.error;
|
||||
};
|
||||
|
||||
return {
|
||||
gate: {
|
||||
admit<T>(invoke: () => T): T {
|
||||
check();
|
||||
return invoke();
|
||||
},
|
||||
signal: controller.signal,
|
||||
},
|
||||
control: {
|
||||
beginAbort(cancellation) {
|
||||
if (state.status !== "open") return;
|
||||
state = { status: "aborting", cancellation };
|
||||
},
|
||||
signalAbort() {
|
||||
if (state.status !== "aborting" || controller.signal.aborted) return;
|
||||
controller.abort(new AbortRequested(state.cancellation));
|
||||
},
|
||||
close(error) {
|
||||
if (state.status === "closed") return;
|
||||
state = { status: "closed", error };
|
||||
if (!controller.signal.aborted) controller.abort(error);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user