/** * Multi-threaded parser worker pool for bulk indexing. * * Spawns N worker threads (N = CPU cores - 1, clamped to [1, 4]) that share * the file-parsing load during startup/full reindex passes. Each worker runs * `parser-worker-script.ts`, parses file content supplied by the main thread * via `parseFileContent`, and returns `FileSymbols[]`. * * The main thread distributes files in round-robin chunks, collects results, * and performs all SQLite writes via `commitBatch`. Workers never touch the * database — single-writer WAL semantics are preserved. * * Failover (P3.7): every response carries the responding worker's * `workerId` (threadId), so busy-tracking is identity-based and a batch * knows exactly which chunk each worker owes. When a worker dies mid-batch, * its orphaned chunk is re-parsed inline on this thread instead of waiting * for a response that never arrive — a partial pool death previously hung * the batch until the outer 60s/240s watchdog. Only when every worker dies * does the batch reject, letting the indexer's existing inline fallback * take over. * * The pool is created lazily on first use and terminated on shutdown. Workers * are `unref()`'d so they don't keep the process alive. */ import type { FileSymbols, SymbolLang } from './schema.js'; /** * Effective pool threshold for this run (audit T-04): the documented * {@link WORKER_POOL_THRESHOLD} default unless `WRONGSTACK_INDEX_WORKER_THRESHOLD` * overrides it. Re-resolved on every call — like `resolveParallelBatch` — so * profile changes (and tests) apply per index run without a process restart. * * - unset / unparsable / negative → the 500 default * - `0` → disables the worker path (per the `WRONGSTACK_*=0` opt-out * convention, e.g. `WRONGSTACK_TOOLCHAIN_BATCH=0`): no candidate count can * satisfy `>= 0 && parseBatchCount > 1` gate semantics with an explicit * disable, so the gate checks the disable first. */ export declare function resolveWorkerPoolThreshold(): number; export declare class ParserWorkerPool { private readonly maxWorkers; private workers; private nextBatchId; private pending; private creating; private unavailable; constructor(maxWorkers?: number); /** * True if the pool is available for use. Returns false when: * - Worker threads aren't supported (sandbox, exotic runtime) * - The built worker script can't be found * - Pool creation was attempted and failed */ isAvailable(): boolean; /** * Lazily create the worker pool. Returns true if the pool is ready, false * if it's unavailable (caller should fall back to inline parsing). */ ensureReady(): Promise; /** * Parse files in parallel across the worker pool. Returns a flat * `FileSymbols[]` in completion order (caller matches by file path). * * Content is pre-read by the main thread (for the content-hash check) * and passed to workers to avoid a second disk read. Files are * distributed round-robin across workers. */ parseFiles(files: ReadonlyArray<{ file: string; content: string; lang: SymbolLang; }>): Promise; /** Shut down all workers. Safe to call multiple times. */ shutdown(): Promise; private handleMessage; /** * Remove a worker from the pool and salvage any chunk it still owed. * * Idempotent by workerId — `error` and `exit` can both fire for one * death, and a worker may die while no batch references it. When the * dead worker owed files to an in-flight batch and other workers remain, * those files are re-parsed inline on this thread (one fewer worker * should cost latency, not correctness). When it was the last worker, * every remaining batch rejects so the indexer's existing inline * fallback takes over the whole batch. */ private retireWorker; /** * Salvage path: re-parse an orphaned chunk on this thread. Files that * fail here stay absent from the results — same contract as a per-file * error inside a live worker (see handleMessage). */ private reparseInline; /** * Terminal tail of a salvage — runs on every exit path. Kept free of * control flow inside a `finally` (noUnsafeFinally): releases the * pending-marker and resolves the batch if this was its last chunk. */ private finishSalvage; /** * Retire by worker object rather than threadId. `threadId` is -1 before * the worker emits `online`, so a death during script load would make a * threadId-keyed lookup silently no-op and leak the entry (with its * pending chunk) — reference identity is correct in every case. */ private retireByReference; private handleError; } /** * Lazily-created process-wide singleton. Returns null when worker threads * are unavailable (sandbox, exotic runtime) or the compiled worker script * can't be found — callers must fall back to inline parsing in that case. */ export declare function getParserPool(): ParserWorkerPool | null; //# sourceMappingURL=parser-worker-pool.d.ts.map