Skip to content

feat(replay): Replay-Bypass side-effect guard (ADR-0027)#9

Merged
muhammetsafak merged 1 commit into
mainfrom
feat/replay-bypass
Jun 19, 2026
Merged

feat(replay): Replay-Bypass side-effect guard (ADR-0027)#9
muhammetsafak merged 1 commit into
mainfrom
feat/replay-bypass

Conversation

@muhammetsafak

Copy link
Copy Markdown
Member

Closes ADR-0026's phase two: a deliberate replay re-runs the handler, and its external side-effects re-fire (a second charge, a duplicate email). Idempotency stops an accidental duplicate; this stops the intended reprocess from re-firing effects that already happened. Implements ADR-0027.

What (backward-compatible capability upgrade)

  • ReceivedMessage.Headers — additive map[string]string of out-of-band transport headers (nil-safe).
  • HeaderPublisher — an optional Transport interface (PublishWithHeaders); transports that don't implement it just don't propagate headers. No existing transport changes to compile. InMemoryTransport implements it.
  • Redrive Bypass option — stamps the bq-replay-bypass header on redriven messages (best-effort: a no-op, Bypassed=false, on a transport that can't carry headers).
  • The runtime surfaces the header to the handler's context; IsReplay(ctx) + BypassExternalEffects(ctx, fn) let a handler skip the external, non-idempotent side on a replay while still running the idempotent core.

Tests

5 tests via InMemoryTransport incl. the end-to-end path (redrive Bypass → header carried → dispatch surfaces it → BypassExternalEffects skips the effect) and the fallback when the transport isn't a HeaderPublisher. Coverage 93.8%, -race clean; existing tests unchanged. Envelope frozen (GR-1).

Rollout

Concrete broker transports projecting the header onto native metadata, and the other SDKs, follow — like the broker bindings themselves.

🤖 Generated with Claude Code

…eliberate replay (ADR-0027)

Backward-compatible capability upgrade: ReceivedMessage gains an additive Headers map; an optional HeaderPublisher interface (transports MAY implement) carries out-of-band headers; InMemoryTransport implements it. Redrive's new Bypass option stamps a bq-replay-bypass header; the runtime surfaces it to the handler's context; IsReplay + BypassExternalEffects let a handler re-run its idempotent core but skip effects that already fired. No envelope change (GR-1), no breaking Transport change. Concrete broker transports + other SDKs to follow.
@muhammetsafak muhammetsafak merged commit e7405c4 into main Jun 19, 2026
12 checks passed
@muhammetsafak muhammetsafak deleted the feat/replay-bypass branch June 19, 2026 07:11
@muhammetsafak muhammetsafak restored the feat/replay-bypass branch June 20, 2026 03:19
@muhammetsafak muhammetsafak deleted the feat/replay-bypass branch June 20, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant