@quanticjs/events-redis
v8.2.0
Published
Redis Streams transport for @quanticjs/events-core — RedisStreamPublisher, RedisStreamConsumer
Readme
@quanticjs/events-redis
Redis Streams transport for QuanticJS domain events: RedisStreamPublisher (XADD) and the abstract RedisStreamConsumer (XREADGROUP consumer groups).
⚠️ Reliability notice — The Redis Streams transport provides weaker delivery guarantees than the Kafka transport. Use it for non-critical eventing only unless you enable and tune:
minIdleTimeMs/reclaimIntervalMs(orphan reclaim),maxDeliveries(poison-message DLQ), and leavemaxStreamLengthunset (no trimming). Streams have no replication-acknowledged durability equivalent to Kafkaacks=-1.
Minimum supported Redis: 6.2 (XAUTOCLAIM). On older Redis, orphaned-entry reclaim is disabled with an error log and only the startup PEL drain runs.
Usage
QuanticEventsRedisModule.forRoot({
consumer: {
minIdleTimeMs: 60_000, // entries idle longer are reclaimable from dead consumers
reclaimIntervalMs: 30_000, // XAUTOCLAIM loop period
maxDeliveries: 5, // delivery-count cap before dead-lettering
readBatchSize: 10,
blockMs: 5_000,
},
publisher: {
// maxStreamLength: 100_000, // OFF by default — see "Stream retention" below
},
})Consumer options can also be passed per consumer through the RedisStreamConsumer constructor's second argument (these defaults apply when omitted).
Reliability behavior
- Orphan reclaim — a periodic
XAUTOCLAIMloop claims entries idle ≥minIdleTimeMsfrom any consumer in the group (including dead pods) and reprocesses them. SetminIdleTimeMsabove your worst-case handler time, otherwise an entry still being processed can be claimed and processed twice (inherent to streams; the inbox primitive dedups command effects if used). - Poison messages / DLQ — an entry whose delivery count exceeds
maxDeliveriesis appended to<streamKey>:dlq(full original fields plusoriginalId,stream,group,deliveryCount,deadLetteredAt— replayable) and thenXACKed. The DLQ write happens before the ack, so a failed DLQ write loses nothing. DLQ streams are never trimmed by this package; monitor and drain them operationally. - Startup PEL drain — on boot the consumer drains its entire pending-entries list in batches before live tailing begins.
- Ordinary failures — a failed entry is left un-acked in the PEL; the reclaim loop retries it after
minIdleTimeMsuntilmaxDeliveriesroutes it to the DLQ.
Stream retention
RedisStreamPublisher performs no trimming by default — streams grow unbounded. Pick one:
- Set
publisher.maxStreamLengthconsciously, sized to worst-case consumer backlog. Trimming is approximate (MAXLEN ~) and silently drops unconsumed entries once the cap is passed. - Leave it unset and run an operational retention job (periodic
XTRIMafter checking consumer-group lag).
