()
| 267 | } |
| 268 | |
| 269 | private spawnOne(): void { |
| 270 | if (this.destroyed || this.workers.size >= this.maxSize || !this.healthy) return; |
| 271 | let w: ParsePoolWorker; |
| 272 | try { |
| 273 | w = this.createWorker(); |
| 274 | } catch { |
| 275 | this.totalCrashes++; // counts toward the circuit breaker |
| 276 | return; |
| 277 | } |
| 278 | this.workers.add(w); |
| 279 | this.pending.add(w); |
| 280 | this.parseCounts.set(w, 0); |
| 281 | w.on('message', (m) => this.onMessage(w, (m ?? {}) as ParseWorkerMessage)); |
| 282 | w.on('error', (e) => this.onWorkerGone(w, `Worker error: ${e?.message ?? 'unknown'}`)); |
| 283 | w.on('exit', (code) => { if (code !== 0) this.onWorkerGone(w, `Worker exited with code ${code}`); }); |
| 284 | // Load grammars; the worker replies 'grammars-loaded' and only then is idle. |
| 285 | // Pre-read WASM bytes (when the orchestrator provided them) make this a |
| 286 | // memory load instead of a per-spawn disk read. |
| 287 | w.postMessage({ type: 'load-grammars', languages: this.languages, grammarBuffers: this.grammarBuffers }); |
| 288 | } |
| 289 | |
| 290 | private onMessage(w: ParsePoolWorker, m: ParseWorkerMessage): void { |
| 291 | if (m.type === 'grammars-loaded') { |
no test coverage detected