/** * @module settle * @category Internal * * Debounced correlate→drain loop. Sits one level above both correlation * and drain: schedule() coalesces rapid callers into a single cycle, then * runs correlate+drain in a loop until a pass produces no progress. * * Owns the debounce timer and the reentrancy flag. Everything else is * supplied via the `SettleDeps` callbacks so this module stays free of * orchestrator state. * * @internal */ import type { Drain, DrainOptions, Query, Schemas, SettleOptions } from "../types/index.js"; import type { CircuitBreaker } from "./circuit-breaker.js"; /** * Callbacks the settle loop needs from the orchestrator. Modeled as an * input bag so this file doesn't import `Act` (avoids a cycle) and stays * independently testable. * * @internal */ export type SettleDeps = { readonly init: () => Promise; readonly checkpoint: () => number; readonly correlate: (query: Query) => Promise<{ subscribed: number; last_id: number; scanned?: boolean; }>; readonly drain: (options: DrainOptions) => Promise>; readonly on_settled: (drain: Drain) => void; /** * Shared orchestrator circuit breaker (ACT-984). The settle loop's * `correlate` (subscribe + query) is a store consumer too: a successful * pass records `passed()`, a failed one `failed(now, err)` — feeding the * same breaker that paces the drain loop, which also surfaces the failure * to the `error` lifecycle event. */ readonly breaker: CircuitBreaker; }; /** * Drives the debounced correlate→drain catch-up cycle. One instance per * Act orchestrator. * * @internal */ export declare class SettleLoop { private _timer; private _running; /** * Resolves when the cycle currently in flight finishes; `undefined` when * idle (#1468). `_running` answers "is a cycle running?" for the * re-arm bookkeeping; this answers "tell me when it is done" for a * graceful shutdown. * * `stop()` only cancels *scheduling* — a cycle already inside its * correlate → drain loop keeps going, and because `DrainController.drain` * does not consult `_stopped`, it can claim a stream after teardown * returned and after the store adapter was disposed. Never rejects: the * cycle's own `catch` contains its errors, so awaiting this is safe. */ private _inflight; /** * Set when a `schedule()` timer fires while a cycle is still running * (ACT-1205). The in-flight cycle's `finally` re-arms one more pass so * the wake-up isn't dropped — a commit landing during the final * no-progress drain pass would otherwise leave armed controllers with * nothing to re-drain on an instance with no lane `cycleMs` and no * polling. Carries the options of the dropped call so the re-armed * pass honors its `debounceMs`/`maxPasses`/drain overrides. */ private _pending; private readonly _deps; /** Debounce window applied when the caller doesn't override via `SettleOptions.debounceMs`. */ private readonly _default_debounce_ms; constructor(deps: SettleDeps, default_debounce_ms: number); /** * Schedule a settle pass. Multiple calls inside the debounce window * coalesce into one cycle. The cycle runs correlate→drain in a loop * until no progress is made (no new subscriptions, no acks, no blocks) * or `maxPasses` is reached, then emits the `"settled"` lifecycle event * via {@link SettleDeps.on_settled}. */ schedule(options?: SettleOptions): void; /** * The cycle currently in flight, or `undefined` when idle (#1468). A * graceful shutdown awaits this alongside the drain controllers so a * settle parked in `correlate` does not resume after teardown. */ get inflight(): Promise | undefined; /** Cancel any pending or active settle cycle. Idempotent. */ stop(): void; } //# sourceMappingURL=settle.d.ts.map