Phase 9: Faster Write-Back (CAL-15) — event-driven outbox drain #14
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* In-process outbox drain signal (D-01 / D-03 / D-04).
|
||||
*
|
||||
* Module-level singleton EventEmitter — one emitter shared across all callers
|
||||
* in this Node.js process. Carries a zero-payload 'drain' event: signal is
|
||||
* fire-and-forget; no data crosses this boundary (D-04).
|
||||
*
|
||||
* Single-subscriber design:
|
||||
* - signalOutboxDrain() is called only after a successful enqueue DB commit (D-01/D-03).
|
||||
* - The sole listener is registered by initOutboxTrigger() in outboxWorker.ts.
|
||||
* - With exactly one subscriber the default EventEmitter limit of 10 is correct.
|
||||
* - Do NOT call setMaxListeners — unlike listEmitter.ts (T-04-04, 200 SSE fan-out),
|
||||
* this emitter never fans out to multiple listeners.
|
||||
*
|
||||
* Exports: signalOutboxDrain, onOutboxDrain
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'node:events';
|
||||
|
||||
// Module-level singleton — one emitter shared across all route handlers
|
||||
// in this Node.js process.
|
||||
const emitter = new EventEmitter();
|
||||
|
||||
/**
|
||||
* Fire a drain signal after a successful outbox enqueue commit.
|
||||
* Synchronous and fire-and-forget — never awaited (D-04).
|
||||
*/
|
||||
export function signalOutboxDrain(): void {
|
||||
emitter.emit('drain');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler to be invoked on each drain signal.
|
||||
* Returns an unsubscribe function; call it to stop delivery to this handler.
|
||||
*/
|
||||
export function onOutboxDrain(handler: () => void): () => void {
|
||||
emitter.on('drain', handler);
|
||||
return () => emitter.off('drain', handler);
|
||||
}
|
||||
Reference in New Issue
Block a user