import type { CatchupJob } from './types.js'; /** * Grace period the shutdown drain gives in-flight walks to settle normally. * * Sized against `SHUTDOWN_HARD_TIMEOUT_MS` (15 s): 5 s here plus the 2 s * terminal-flush reserve leaves ~8 s for runner close, `agent.stop()`, the * final telemetry shutdown and the database close. */ export declare const CATCHUP_SHUTDOWN_DRAIN_BUDGET_MS = 5000; /** Which of the two mint sites produced a job. */ export type CatchupAdmission = 'walk' | 'synthetic'; /** * Closed `result` vocabulary for I7 — one value per subscribe-route return. * `shutting_down` covers BOTH admission guards; they are distinguishable by * `admission` on the job side only when a job exists, which for a 503 it never * does, and that is the point. */ export type CatchupRequestResult = 'bad_request' | 'forbidden' | 'deduped' | 'ready_replay' | 'ready_synthetic' | 'queued' | 'shutting_down'; /** * A job whose terminal record is still owed, plus the continuation that will * produce it. * * `terminalRecorded` lives on THIS object rather than being derived from * `catchupTracker.jobs`, and the difference is load-bearing: that map prunes * to 100 entries by oldest `queuedAt` regardless of status, so a long-running * job can be evicted while still in flight. Keying idempotency off it would * let a job be counted twice, or not at all. */ export interface CatchupJobLedgerEntry { readonly job: CatchupJob; readonly admission: CatchupAdmission; /** * Monotonic start for I9. `Date.now()` deltas can go negative across an NTP * step, and catch-up walks are long enough (measured runs of 305 s and * 382 s) for that to be a real sample. */ readonly startedAtMono: number; /** Retained continuation; the shutdown drain awaits it. Never rejects. */ task?: Promise; terminalRecorded: boolean; } /** I7 — one point per subscribe-route return. Never throws. */ export declare function recordCatchupRequest(result: CatchupRequestResult, includeSharedMemory: boolean): void; /** * I8 (+ I9 for walks) — at most one point per jobId, ever. * * Synchronous and non-throwing by construction, because the walk call site is * a detached task's `finally`. The idempotency bit is set BEFORE the record so * that even a throw inside the metric API cannot produce a second point. */ export declare function recordTerminalOnce(entry: CatchupJobLedgerEntry): void; /** * Register a walk job and return its ledger entry. The caller assigns * `entry.task` once the continuation exists, and must pass the ENTRY (not the * jobId) into that closure, so releasing the map slot cannot erase the * idempotency bit before a late `finally` runs. */ export declare function beginWalkCatchupJob(job: CatchupJob): CatchupJobLedgerEntry; /** * Drop a settled walk job from the drain set. Deletes only if the slot still * holds THIS entry, so a re-used id can never evict a newer job. */ export declare function releaseCatchupJob(entry: CatchupJobLedgerEntry): void; /** I8 for the already-ready mint: born terminal, recorded immediately. */ export declare function recordSyntheticCatchupJob(job: CatchupJob): void; /** * Grace drain for graceful shutdown: let in-flight walks settle normally, * then record a terminal point for every job still owed one. * * MUST run while the catch-up runner's worker is still alive. `close()` IS * `worker.terminate()`, and the constructor-registered `exit` handler rejects * every pending run — so draining after termination grants no grace at all, it * merely observes every job being forced onto its `failed` path. * * Bounded by `budgetMs`: on expiry the still-running jobs are recorded as * `failed` and their late `finally` becomes a no-op, so a hung walk cannot eat * the shutdown deadline. */ export declare function drainCatchupJobs(budgetMs: number, log?: (message: string) => void): Promise<{ drained: number; expired: boolean; }>; /** Test seam: the ledger is process-global, like `daemonState`. */ export declare function resetCatchupJobLedger(): void; /** Test seam: current in-flight walk count. */ export declare function catchupLedgerSize(): number; //# sourceMappingURL=catchup-telemetry.d.ts.map