Problem
xstreamroll_messages_processed_total is always zero. incrementProcessed() is defined in xstreamroll-processing/src/metrics.ts and exercised only by its own unit test (xstreamroll-processing/__tests__/metrics.test.ts); no production code path ever calls it. The worker's per-event success path is in StreamSession.pump() (xstreamroll-processing/src/session.ts), which emits a "processed" event after a successful publish but never touches the metrics module. Meanwhile the worker's dead-letter path logs, and the dead-letter event has no subscriber, so processed-vs-failed counts are unobservable: dashboards built on the advertised metric (README documents xstreamroll_* metrics) show zero processed messages forever, and the error/processed ratio is meaningless.
Root cause
// xstreamroll-processing/src/session.ts — pump()
await this.handlers.publish(processed)
this.emit("processed", processed) // ← the success signal
// ... but nothing calls metrics.incrementProcessed()
// xstreamroll-processing/src/metrics.ts
export function incrementProcessed(): void { // ← zero callers outside tests
counters.messagesProcessed++
}
Acceptance criteria
Out of scope
The durable dead-letter store (separate issue), and adding new metrics beyond wiring the existing counter.
Getting started
Real files in scope: xstreamroll-processing/src/session.ts (pump), xstreamroll-processing/src/metrics.ts, xstreamroll-processing/__tests__/session.test.ts, xstreamroll-processing/__tests__/metrics.test.ts.
Verify with:
cd xstreamroll-processing && npm run typecheck && npm test
Good first files to read: xstreamroll-processing/src/session.ts (the publish-retry loop in pump), xstreamroll-processing/src/metrics.ts.
Problem
xstreamroll_messages_processed_totalis always zero.incrementProcessed()is defined inxstreamroll-processing/src/metrics.tsand exercised only by its own unit test (xstreamroll-processing/__tests__/metrics.test.ts); no production code path ever calls it. The worker's per-event success path is inStreamSession.pump()(xstreamroll-processing/src/session.ts), which emits a"processed"event after a successful publish but never touches the metrics module. Meanwhile the worker's dead-letter path logs, and thedead-letterevent has no subscriber, so processed-vs-failed counts are unobservable: dashboards built on the advertised metric (README documentsxstreamroll_*metrics) show zero processed messages forever, and the error/processed ratio is meaningless.Root cause
Acceptance criteria
messagesProcessedexactly once, including after a transient publish failure that succeeds on retry (the increment happens only on success).messagesProcessed; they are observable via the existing error/dead-letter path (thedead-letterevent or a counter chosen in the design).GET /metricson the worker's metrics server (xstreamroll-processing/src/metrics.tsstartMetricsServer) reflects the incremented value after events flow through a session.xstreamroll-processing/__tests__/(e.g.session.test.tsormetrics.test.ts) asserts the increment fires on success and not on failure.Out of scope
The durable dead-letter store (separate issue), and adding new metrics beyond wiring the existing counter.
Getting started
Real files in scope:
xstreamroll-processing/src/session.ts(pump),xstreamroll-processing/src/metrics.ts,xstreamroll-processing/__tests__/session.test.ts,xstreamroll-processing/__tests__/metrics.test.ts.Verify with:
Good first files to read:
xstreamroll-processing/src/session.ts(the publish-retry loop inpump),xstreamroll-processing/src/metrics.ts.