Skip to content

5.x backport of #4952: stop the database control listener without waiting out its poll delay - #4954

Merged
jeremydmiller merged 1 commit into
5.0from
backport-4952-control-listener-cancellation
Oct 11, 2026
Merged

jeremydmiller merged 1 commit into
5.0from
backport-4952-control-listener-cancellation

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Backport of #4952 (me-azlam-kp) to the 5.0 branch, cherry-picked from f9f7424 with the author's commit kept.

On 5.x the control listener's delay between polls is a fixed one second rather than 6.x's idle backoff, so the worst case was about one second instead of five, but the defect is the same: neither Task.Delay in DatabaseControlListener observed the listener's cancellation while StopAsync awaited the loop, so stopping a node waited out whatever was left of the sleep before endpoint draining, ownership release and node deregistration could run. CosmosDbControlListener had the same shape and gets the same change.

What differs from the 6.x commit

  • The poll-delay hunk is resolved against 5.x's Task.Delay(1.Seconds()); there is no idle interval to pass through.
  • The test is adapted to the one-second shape: it waits for the first poll, which puts the loop straight into its one-second sleep, then calls StopAsync and asserts it returns in under 250 ms. Verified red-then-green against this branch: with the pre-fix listener swapped back in it fails on the full second, with the fix it passes.
  • TestContext.Current is xUnit v3 and 5.x is on v2, so the wait uses a plain timeout.

Verified: PersistenceTests database_control_listener_shutdown on net9.0; dotnet build wolverine.slnx -c Release -f net9.0 clean on this branch.

🤖 Generated with Claude Code

DatabaseControlListener slept between polls with Task.Delay and no
cancellation token, and StopAsync awaits the polling loop. Once the control
queue has been quiet for ten seconds that sleep is five seconds, so stopping
a quiet node could wait up to five seconds before endpoint draining,
ownership release and node deregistration ran. CosmosDbControlListener had
the same shape with a one second delay.

Both loops now pass the listener's cancellation token to the startup stagger
and to the delay between polls, treat cancellation as a normal stop, and
StopAsync tolerates a loop that ended cancelled. This matches what
OracleControlListener already does.
@jeremydmiller
jeremydmiller merged commit 3308b0a into 5.0 Oct 11, 2026
21 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