/** * The engine's concurrency seam (spec §3.5/§3.6/§9.5): a deterministic, promise-driven bounded-pool * scheduler used by `.parallel` and `.foreach(concurrency > 1)`. No timers, no real races — every * transition here is a plain promise resolution, so a test can force ANY interleaving it wants simply * by controlling exactly when the tasks IT supplies resolve (e.g. hand-rolled deferred promises a step * body awaits) — never by hoping about scheduling. This is what makes concurrency testable without a * green suite hiding a race (see the module's tests, scheduler.test.ts, and the workflow-level * concurrency tests in parallel.test.ts / foreach-concurrency.test.ts). * * Two pieces, deliberately unaware of each other: * - {@link ConcurrencyGate} — the RUN-WIDE ceiling (spec §3.6): one instance per run, shared by every * construct (including nested workflows, which inherit it — see `RunState.concurrencyGate`). It is * held by a STEP, for exactly as long as that step executes (`runStepNode`, execute.ts), so the * ceiling bounds "steps executing at once" across the whole tree, exactly as spec §3.6 words it. * Gating the enclosing CONSTRUCT instead would deadlock the moment constructs nest: a foreach at the * ceiling would hold every slot while its items waited for slots for their own inner fan-out. * - {@link runConcurrent} — runs one construct's own items/arms, bounded by a LOCAL cap (a foreach's * own `concurrency`, or the ceiling for a parallel, which declares none). Since a leaf step is what * holds a gate slot, this needs no gate of its own — lanes are the construct's shape, slots are the * run's budget. Implements drain-then-crash (spec §9.5): once any settled result asks to stop, no * further items START: already running ones finish naturally. * * Pure — no fs/PI/network/setTimeout. */ /** A run-wide semaphore (spec §3.6): at most `limit` holders at once, FIFO wake order. */ export interface ConcurrencyGate { /** The ceiling this gate was sized to — also what a `.parallel` (which declares no cap of its own) uses as its lane count. */ readonly limit: number; /** Resolve once a slot is free (immediately if one already is). */ acquire(): Promise; /** Release a held slot, waking the longest-waiting queued acquirer, if any. */ release(): void; } /** Create a fresh gate sized to a run's concurrency ceiling (spec §3.6). */ export declare function createConcurrencyGate(limit: number): ConcurrencyGate; /** * Run `items` through `worker` in at most `localLimit` lanes — this construct's own concurrency cap (a * foreach's declared `concurrency`, or the run's ceiling for a parallel, which declares none). Results * land at their ITEM'S OWN INDEX in the returned array regardless of completion order (spec §3.4/§3.5's * item/name-ordering guarantee starts here). The run-wide ceiling is enforced one level down, by the * steps themselves (see the module header), so nothing here touches the gate. * * Drain-then-crash (spec §9.5): `shouldStop` is checked against each settled result; once it returns * true, no further items are STARTED — a lane claims its next item only after its current one settled, * so the check is always seen before the claim. Items already running are not interrupted: they finish * and checkpoint normally, per spec. Items that never start stay whatever `results[i]` starts as (the * caller distinguishes "ran" from "never started" itself, e.g. via a discriminated `TResult`). */ export declare function runConcurrent(items: readonly TItem[], worker: (item: TItem, index: number) => Promise, localLimit: number, shouldStop: (result: TResult) => boolean): Promise<(TResult | undefined)[]>; //# sourceMappingURL=scheduler.d.ts.map