Synchronous delivery for determinism. Tests are reproducible and
the patterns are legible. Production is async over a durable log
(pa-04); the GUIDE's exercises add bounded async + backpressure.
Dedup per subscription, keyed by event id. Each consumer owns its
idempotency; the bus doesn't assume a global dedup. This matches
reality (consumers dedup independently).
Don't cache failures into seen. Only a successful handle marks
the id seen, so a transient failure is retried, not silently skipped.
DLQ after maxRetries, with attempt count + reason. Operators need
why and how-many to triage and replay.
At-least-once vs exactly-once. We choose at-least-once + idempotent
consumers — the only honest option end-to-end. Brokers' "exactly-once"
stops at the broker boundary; your side effects still need idempotency.
Ordering. This bus preserves per-publish order to each subscriber
but offers no cross-event ordering guarantee; real ordering is
per-partition (pa-04). Don't design consumers that assume global order.
Backpressure vs shed. Synchronous delivery = implicit backpressure
(the publisher waits). An async bus must choose bound + overflow policy;
unbounded = deferred OOM.
DLQ is not a graveyard. Un-replayed DLQs hide real failures; alert
on depth and have a replay path.