Skip to content

feat(batching): warn/assert on a direct handler shadowing a batch handler (GH-3289 Phase 2)#3301

Merged
jeremydmiller merged 1 commit into
mainfrom
feat-batching-phase2-collision-diagnostic-3289
Jul 5, 2026
Merged

feat(batching): warn/assert on a direct handler shadowing a batch handler (GH-3289 Phase 2)#3301
jeremydmiller merged 1 commit into
mainfrom
feat-batching-phase2-collision-diagnostic-3289

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Phase 2 of the #3289 batch-processing plan — item 6, downscoped to a startup diagnostic. (Phase 0 #3299 merged; Phase 1 is #3300.)

The silent footgun

Under the default MultipleHandlerBehavior.ClassicCombineIntoOneLogicalHandler, a message type that has both a direct Handle(T) handler and a BatchMessagesOf<T>() batch handler silently shadows the batch: the direct handler wins and the batch handler never runs. Separated mode already resolves this legitimately (the batch is moved to its own -batch queue and both run) via reassignBatchQueuesThatCollideWithHandlers(). Only the Classic case was silent.

Change

  • New warnOrAssertBatchHandlerConflicts() runs at startup right after the existing reassignBatchQueuesThatCollideWithHandlers() in WolverineRuntime.HostService. In Classic mode, for each batch definition whose element type also has a direct handler chain (Handlers.ChainFor(elementType) != null — the batch handler is a separate chain for T[]), it logs a loud warning naming both handlers and pointing at MultipleHandlerBehavior.Separated.
  • Opt-in opts.AssertNoBatchHandlerConflicts() makes Wolverine throw at startup instead of warning.
  • No-ops under Separated mode and when there is no colliding direct handler (the normal batch-only case).

Tests

src/Testing/CoreTests/Acceptance/batch_handler_conflict_diagnostic.cs:

  • default → warning logged (captured via the existing CapturingLogger), naming both roles + the fix;
  • opt-in → StartAsync throws InvalidOperationException;
  • batch-only → no warning/throw;
  • Separated + both handlers → stays silent even when opted in.

All 4 green; existing batch acceptance tests unaffected. dotnet build wolverine.slnx -c Release clean.

Docs

docs/guide/handlers/batching.md: a warning callout in the "Combining a direct handler with batching" section covering the startup warning and the AssertNoBatchHandlerConflicts() opt-in.

🤖 Generated with Claude Code

…h handler in Classic mode (GH-3289 Phase 2)

Phase 2 of the #3289 batch-processing plan (item 6, downscoped to a diagnostic).

Under the default MultipleHandlerBehavior.ClassicCombineIntoOneLogicalHandler, a
message type that has BOTH a direct Handle(T) handler and a BatchMessagesOf<T>()
batch handler silently shadows the batch — the direct handler wins and the batch
handler never runs. Separated mode already resolves this legitimately (the batch
moves to its own -batch queue); only the Classic case was a silent footgun.

- New warnOrAssertBatchHandlerConflicts() runs at startup right after the existing
  reassignBatchQueuesThatCollideWithHandlers(). In Classic mode, for each batch
  definition whose element type also has a direct handler chain, it logs a loud
  warning naming both handlers and pointing at MultipleHandlerBehavior.Separated.
- Opt-in WolverineOptions.AssertNoBatchHandlerConflicts() makes it throw at startup
  instead of warning.
- No-ops under Separated mode and when there is no colliding direct handler.

Tests cover the default warning (captured via the existing CapturingLogger), the
opt-in throw, the batch-only (no conflict) case, and Separated mode staying silent.
Docs updated in the "Combining a direct handler with batching" section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeremydmiller
jeremydmiller merged commit 2da8c86 into main Jul 5, 2026
26 checks passed
This was referenced Jul 9, 2026
This was referenced Jul 14, 2026
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