Skip to content

Additional error actions apply to the open-ended attempts of indefinite policies - #5259

Merged
jeremydmiller merged 1 commit into
mainfrom
gh-5252-indefinite-additional-actions
Oct 28, 2026
Merged

jeremydmiller merged 1 commit into
mainfrom
gh-5252-indefinite-additional-actions

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Follow-up to #5252 (johnkaram02), which made actions chained after ScheduleRetryIndefinitely() apply to its listed delays. As that PR's description pointed out, the attempts after the listed delays still came from FailureRule.InfiniteSource, which is a bare continuation source with nowhere to put additional actions.

Given

opts.OnException<X>()
    .ScheduleRetryIndefinitely(1.Minutes(), 5.Minutes())
    .AndPauseProcessing(10.Minutes());
Attempt Before After
1 retry in 1 min + pause same
2 retry in 5 min + pause same
3 and later retry every 5 min, no pause retry every 5 min + pause

The same gap made RequeueIndefinitely().AndPauseProcessing(...) never pause at all. It also dropped additional actions from CustomActionIndefinitely(), and from ContinueWith() after its first attempt.

Change

  • FailureRule keeps its infinite source in a FailureSlot of its own (InfiniteSlot) and builds the open-ended attempts from it, so they combine with additional actions exactly as a numbered slot does.
  • InfiniteSource still returns the source that was set, with no actions attached. The Kafka and Pulsar transports read it to recognise their native policies, and Pulsar sets it directly.
  • FailureActions applies AndPauseProcessing / AndPauseSending / And(...) to that slot while it belongs to the current segment of the chain. Then clears it, as it already clears the numbered slots, so ScheduleRetry(1m).AndPauseProcessing(5m).Then.RequeueIndefinitely() does not pause on the requeues.
  • FailureRule.ToString() describes the open-ended attempts with their additional actions.

Tests

FailureRuleCollectionTests gets five tests:

  • ScheduleRetryIndefinitely keeps pausing after its listed delays
  • RequeueIndefinitely().AndPauseProcessing(...)
  • CustomActionIndefinitely(...).And<...>()
  • additional actions stay with their own segment of the chain
  • the rule's description

The first three fail on main and pass with this change.

Local verification (net9.0, Release):

  • dotnet build wolverine.slnx -c Release -f net9.0: clean
  • CoreTests, full suite: 3932 passed, 8 skipped, 0 failed

🤖 Generated with Claude Code

https://claude.ai/code/session_01DCggXgxnG3EBXoR9rrq37U

…te policies

Follow-up to #5252. FailureRule.InfiniteSource was a bare continuation source, so actions
chained with AndPauseProcessing(), AndPauseSending() or And(...) never reached the attempts
it covers:

- ScheduleRetryIndefinitely(1m, 5m).AndPauseProcessing(10m) paused on attempts 1 and 2,
  then retried every 5 minutes without pausing
- RequeueIndefinitely().AndPauseProcessing(...) never paused at all
- the same gap for CustomActionIndefinitely() and for ContinueWith() after attempt 1

The rule now keeps its infinite source in a FailureSlot of its own, and FailureActions applies
additional actions to it while it belongs to the current segment of the chain (Then clears
it, as it already clears the numbered slots). InfiniteSource still returns the source that was
set, because the Kafka and Pulsar transports read it to recognise their native policies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCggXgxnG3EBXoR9rrq37U
@jeremydmiller
jeremydmiller merged commit 9daa516 into main Oct 28, 2026
47 of 48 checks passed
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