Skip to content

Fix client shutdown deadlock when a message buffer is full - #645

Merged
copybara-service[bot] merged 1 commit into
masterfrom
cl/998560176
Oct 14, 2026
Merged

copybara-service[bot] merged 1 commit into
masterfrom
cl/998560176

Conversation

@copybara-service

Copy link
Copy Markdown

Fix client shutdown deadlock when a message buffer is full

Client.Stop hangs if one of the per-priority buffers for messages to the
server is full, i.e. holds 100 messages or 20 MiB that the server hasn't acked
yet. This is likely on machines that can't reach the server for a while, e.g.
offline laptops, because local services keep sending messages. Then the
process only exits when a watchdog terminates it ungracefully: after 10s on
SIGTERM, and after a minute on a config reload (SIGHUP). After a graceful
Die request, it hangs indefinitely.

Stop waits for the RetryLoops to terminate before it starts acking the
messages left in the outbox, but a RetryLoop at its limit doesn't read its
input until some of its pending messages are acked, so it never notices that
the input was closed.

Stop now starts draining the outbox before it closes the inputs of the
RetryLoops and keeps draining until SortLoop has returned.

The new tests fill a buffer to its count or size limit, without a communicator
and with one that can't deliver messages, and check that Stop returns.
Without the fix, it doesn't return within the tests' 10s timeout.

@copybara-service copybara-service Bot added the exported Exported change from internal source label Oct 13, 2026
@copybara-service
copybara-service Bot force-pushed the cl/998560176 branch 2 times, most recently from 2d41ab8 to a858365 Compare October 14, 2026 16:42
`Client.Stop` hangs if one of the per-priority buffers for messages to the
server is full, i.e. holds 100 messages or 20 MiB that the server hasn't acked
yet. This is likely on machines that can't reach the server for a while, e.g.
offline laptops, because local services keep sending messages. Then the
process only exits when a watchdog terminates it ungracefully: after 10s on
SIGTERM, and after a minute on a config reload (SIGHUP). After a graceful
`Die` request, it hangs indefinitely.

`Stop` waits for the `RetryLoop`s to terminate before it starts acking the
messages left in the outbox, but a `RetryLoop` at its limit doesn't read its
input until some of its pending messages are acked, so it never notices that
the input was closed.

`Stop` now starts draining the outbox before it closes the inputs of the
`RetryLoop`s and keeps draining until `SortLoop` has returned.

The new tests fill a buffer to its count or size limit, without a communicator
and with one that can't deliver messages, and check that `Stop` returns.
Without the fix, it doesn't return within the tests' 10s timeout.

PiperOrigin-RevId: 999443649
@copybara-service
copybara-service Bot merged commit 5e3b97b into master Oct 14, 2026
21 of 22 checks passed
@copybara-service
copybara-service Bot deleted the cl/998560176 branch October 14, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exported Exported change from internal source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants