Comprehensive async-suffixed saga method coverage (GH-3274)#3275
Merged
Conversation
Issue #3274 re-reports #2578: saga methods named with the conventional `Async` suffix (e.g. `StartAsync`, `HandleAsync`) are discovered as handlers but were silently never wired as `Starting`/`Existing`/`NotFound` saga calls, so the saga never started and cascaded continuations parked forever with no error. The `SagaChain.findByNames` fix already shipped on `main` under #2578, but coverage was minimal. This adds an async clone of the `GuidIdentifiedSagaComplianceSpecs` / `BasicWorkflow` synchronous suite that exercises *every* meaningful saga method convention end-to-end with a genuinely async (Task-returning) body and the `Async` suffix: `StartAsync`, `StartsAsync`, `StartOrHandleAsync`, `StartsOrHandlesAsync`, `HandleAsync`, `HandlesAsync`, `ConsumeAsync`, `ConsumesAsync`, `OrchestrateAsync`, `OrchestratesAsync`, and `NotFoundAsync` — at both the discovery level (correct Starting/Existing/NotFound bucket) and the runtime level (method actually invoked, state persisted/deleted, cascades delivered). Reverting the `findByNames` fix fails 25 of the 26 new tests. Also expands the saga Method Conventions doc table to list the `Async` variant of each convention name explicitly, and references #3274 alongside #2578 in the `findByNames` comment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 29, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3274
Background
Issue #3274 re-reports #2578: a saga handler method named with the conventional
Asyncsuffix (e.g.HandleAsync,StartAsync) is discovered as a handler but silently never wired as a sagaStarting/Existing/NotFoundcall, so the saga never starts, cascaded continuations are dropped, and the saga parks forever — with no error or warning.The root cause was an inconsistency:
HandlerDiscoveryregisters both the bare name and theAsync-suffixed name as valid handler methods, butSagaChain.findByNamesmatched the exactMethod.Namewith noAsyncvariant.The
findByNamesfix already shipped onmainunder #2578 (commit250f5dad9), somainis not affected by the bug as reported against 5.26.0. What was missing was thorough regression coverage — the existingBug_2578test only spot-checks a few names.What this PR does
Per the issue's "happy to open a PR with a regression test" offer, this adds an async clone of the synchronous saga compliance suite (
GuidIdentifiedSagaComplianceSpecs/BasicWorkflow) that exercises every meaningful saga method convention end-to-end, using a genuinely async (Task-returning) body and theAsyncsuffix:StartAsync,StartsAsync,StartOrHandleAsync,StartsOrHandlesAsync,HandleAsync,HandlesAsync,ConsumeAsync,ConsumesAsync,OrchestrateAsync,OrchestratesAsync, andNotFoundAsync.Each is verified at two levels:
StartingCalls/ExistingCalls/NotFoundCallsbucket.[SagaIdentity]/ envelope / message-property id resolution paths all work, andNotFoundAsyncruns when the saga is absent.The end-to-end assertions mirror the cloned synchronous tests (
complete, cascading-id-in-header,start_1,start_2, straight update, envelope update,[SagaIdentity]update, indeterminate-id error).Validation: reverting the
findByNamesAsyncmatch to strict equality fails 25 of the 26 new tests, confirming the coverage is meaningful. With the fix in place all 26 (plus the existingBug_25788) pass.Docs
docs/guide/durability/sagas.mdto list theAsyncvariant of each convention name explicitly.Asyncsuffix are silently not wired (discovered but excluded from Starting/Existing calls) #3274 alongside SagaChain.findByNames does not strip Async suffix; saga StartAsync / HandleAsync are discovered but silently skipped #2578 in thefindByNamescomment.Note on 5.x
The bug as filed is against
WolverineFx 5.26.0. Themain(6.x) line already carries the fix; the5.0maintenance branch would need a backport of #2578's one-linefindByNameschange if a 5.x patch is desired.🤖 Generated with Claude Code