Self-heal workers wedged off the broker#118
Merged
Merged
Conversation
Two changes so a single worker that loses its broker connection recovers
without manual intervention, while a genuine fleet-wide broker outage does
not turn into a crash-loop storm:
- Set explicit TCP keepalive options (TCP_KEEPIDLE/INTVL/CNT) on both redis
connection pools. The pools previously passed socket_keepalive_options={},
so a half-open connection (broker endpoint moved, stale conntrack) was only
detected via the 7s per-command socket_timeout and reconnects kept hitting
the same dead endpoint. Active probing reaps a dead socket in ~60s on Linux
so redis-py rebuilds it against a live endpoint. Guarded with hasattr so it
is a no-op on platforms without these options (e.g. macOS dev boxes).
- Add a broker-liveness self-exit. get_task now records success/failure on a
BrokerHealth tracker, and the shared get_tasks poll loop exits non-zero once
the worker has gone longer than broker_unhealthy_exit_sec (default 300s)
without a successful read, so Kubernetes reschedules it with a fresh network
setup. The window is deliberately generous and the health clock starts fresh
on boot, so a real outage recycles the fleet slowly (one restart per window
per pod) rather than crash-looping; set to 0 to disable.
Covered by unit tests for the keepalive options, BrokerHealth accounting,
get_task success/failure recording, and the self-exit threshold behavior.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xLtVzkJYp4Z2SHLgGbTVP
Codecov Report❌ Patch coverage is
... and 6 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
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.
Two changes so a single worker that loses its broker connection recovers without manual intervention, while a genuine fleet-wide broker outage does not turn into a crash-loop storm:
Set explicit TCP keepalive options (TCP_KEEPIDLE/INTVL/CNT) on both redis connection pools. The pools previously passed socket_keepalive_options={}, so a half-open connection (broker endpoint moved, stale conntrack) was only detected via the 7s per-command socket_timeout and reconnects kept hitting the same dead endpoint. Active probing reaps a dead socket in ~60s on Linux so redis-py rebuilds it against a live endpoint. Guarded with hasattr so it is a no-op on platforms without these options (e.g. macOS dev boxes).
Add a broker-liveness self-exit. get_task now records success/failure on a BrokerHealth tracker, and the shared get_tasks poll loop exits non-zero once the worker has gone longer than broker_unhealthy_exit_sec (default 300s) without a successful read, so Kubernetes reschedules it with a fresh network setup. The window is deliberately generous and the health clock starts fresh on boot, so a real outage recycles the fleet slowly (one restart per window per pod) rather than crash-looping; set to 0 to disable.
Covered by unit tests for the keepalive options, BrokerHealth accounting, get_task success/failure recording, and the self-exit threshold behavior.
Claude-Session: https://claude.ai/code/session_014xLtVzkJYp4Z2SHLgGbTVP