()
| 248 | } |
| 249 | |
| 250 | private spawnOne(): void { |
| 251 | if (this.destroyed || this.workers.size >= this.maxSize || !this.healthy) return; |
| 252 | let w: ParsePoolWorker; |
| 253 | try { |
| 254 | w = this.createWorker(); |
| 255 | } catch { |
| 256 | this.totalCrashes++; // counts toward the circuit breaker |
| 257 | return; |
| 258 | } |
| 259 | this.workers.add(w); |
| 260 | this.pending.add(w); |
| 261 | this.parseCounts.set(w, 0); |
| 262 | w.on('message', (m) => this.onMessage(w, (m ?? {}) as ParseWorkerMessage)); |
| 263 | w.on('error', (e) => this.onWorkerGone(w, `Worker error: ${e?.message ?? 'unknown'}`)); |
| 264 | w.on('exit', (code) => { if (code !== 0) this.onWorkerGone(w, `Worker exited with code ${code}`); }); |
| 265 | // Load grammars; the worker replies 'grammars-loaded' and only then is idle. |
| 266 | // Pre-read WASM bytes (when the orchestrator provided them) make this a |
| 267 | // memory load instead of a per-spawn disk read. |
| 268 | w.postMessage({ type: 'load-grammars', languages: this.languages, grammarBuffers: this.grammarBuffers }); |
| 269 | } |
| 270 | |
| 271 | private onMessage(w: ParsePoolWorker, m: ParseWorkerMessage): void { |
| 272 | if (m.type === 'grammars-loaded') { |
no test coverage detected