Skip to content

feat(consumers): Auto-restart on single-partition lag - #8386

Open
sentry-junior[bot] wants to merge 13 commits into
masterfrom
feat/partition-stall-watchdog
Open

feat(consumers): Auto-restart on single-partition lag#8386
sentry-junior[bot] wants to merge 13 commits into
masterfrom
feat/partition-stall-watchdog

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Rust consumers can now fail the Kubernetes health file when one assigned partition stops making useful commit progress, so the pod restarts and Kafka rebalances.

The Snuba healthcheck (--health-check snuba, also selected automatically when the stall timeout is set) adds two per-partition checks on top of the existing file touch:

  • Hard stall — in-flight work with no commit advance past consumer.partition_stall_timeout_secs.
  • Relative slowdown — over one timeout-sized window, a partition’s commit rate is below consumer.partition_slow_ratio (default 0.25) of the leave-one-out sibling median while still receiving work. Set the ratio to 0 for hard-stall only. Quiet assignments (inclusive median under 50 offsets/s) skip this check.

experimental_healthcheck is renamed to consumer.commit_progress_healthcheck (consumer-level commit or idle progress). The old key is gone; it was unused in sentry-options-automator.

Python consumers are unchanged (arroyo poll-only file touch).

Enable with --health-check-file already set:

consumer.partition_stall_timeout_secs: 300
consumer.partition_slow_ratio: 0.25

Relative slowdown needs at least two active partitions on the same pod. Restart only helps when the owning member is the problem; a hot or broken partition can take its lag with it. During backlog recovery, librdkafka can starve sibling partitions and look like slowdown, which would force extra rebalances.

Requested by PDPM.

--

View Junior Session in Sentry

sentry-junior Bot and others added 3 commits August 23, 2026 20:55
Add an option-gated watchdog in the Snuba rust healthcheck that tracks
submit vs commit progress per partition. When a partition has in-flight
work without commit progress past the timeout, stop touching the health
file so the k8s liveness probe restarts the pod and Kafka rebalances.

Co-Authored-By: PDPM <pierre.massat@sentry.io>
Extend the stall watchdog so it also fails health when one assigned
partition's commit rate falls far below the median sibling rate while
still receiving work. That covers the single-partition lag case where
offsets still move slowly and a hard commit stall never fires.

Co-Authored-By: PDPM <pierre.massat@sentry.io>

Co-Authored-By: PDPM <pierre.massat@sentry.io>
@sentry-junior sentry-junior Bot changed the title feat(consumers): Restart on per-partition commit stall feat(consumers): Auto-restart on single-partition lag Aug 23, 2026
getsantry Bot and others added 3 commits August 23, 2026 21:28
Rename experimental_healthcheck to consumer.commit_progress_healthcheck
so the name matches consumer-level commit/idle progress checks. Keep the
old key as a legacy alias. Document strategy and progress modes in the
consumer architecture docs.

Co-Authored-By: PDPM <pierre.massat@sentry.io>
@phacops
phacops marked this pull request as ready for review August 23, 2026 23:25
@phacops
phacops requested a review from a team as a code owner August 23, 2026 23:25
Comment thread rust_snuba/src/strategies/healthcheck.rs Outdated
Compare each partition to the median of the other active partitions on
the assignment. An inclusive median diluted the slow partition on small
assignments, so the default 0.25 ratio missed the two-partition collapse
case.

Co-Authored-By: PDPM <pierre.massat@sentry.io>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9abdb3a. Configure here.

Comment thread rust_snuba/src/strategies/healthcheck.rs Outdated
Keep leave-one-out sibling medians for the ratio comparison, but gate the
whole assignment on an inclusive median quiet floor so one hot partition
cannot fail mostly-quiet peers. Also satisfy clippy::question_mark on the
slow-ratio option helper.

Co-Authored-By: PDPM <pierre.massat@sentry.io>

@onewland onewland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be a bad idea without more safeguards. It has potential to cause a negative feedback loop.

We've seen in backlog situations before that when a consumer is successfully processing multiple partitions of a topic (after a period of not-processing) where all partitions are quite behind that librdkafa and the broker will queue messages for processing based on partition ordering, meaning some partitions will not make progress for a while until the "front-most" partition drops below a certain threshold where the buffer will receive messages from a wider set. If that happens with this change enabled, you'll force more rebalancing and slow down recovery; a similar pattern to OOMing when we hit a backlog

The key is unused in sentry-options-automator, so keep only consumer.commit_progress_healthcheck.
Comment thread rust_snuba/src/strategies/healthcheck.rs Outdated
Comment thread rust_snuba/src/strategies/healthcheck.rs Outdated
Select one file owner with --health-check (arroyo, commit-progress, partition-stall). Drop option-gated modes and relative slowdown. consumer.partition_stall_timeout_secs is only the stall timeout.
Nothing in ops or tests passed --health-check snuba; keep only arroyo, commit-progress, and partition-stall.
Comment on lines +135 to 142
"arroyo: touch on every poll. "
"commit-progress: touch on commit or idle. "
"partition-stall: touch unless a partition has in-flight work with no commit "
"past consumer.partition_stall_timeout_secs."
),
)
def accepted_outcomes_consumer(
*,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The accepted_outcomes_consumer CLI accepts --health-check and --health-check-file arguments, but the Rust implementation ignores them, preventing health checks from functioning as advertised.
Severity: HIGH

Suggested Fix

The Rust implementation for the accepted outcomes consumer in rust_snuba/src/accepted_outcomes_consumer.rs needs to be updated. The accepted_outcomes_consumer_impl function should pass the health_check and health_check_file parameters to the AcceptedOutcomesStrategyFactory. The factory should then include logic to wrap the processing strategy with the appropriate health check wrapper, similar to how it's done in factory_v2.rs for the regular consumer.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: snuba/cli/accepted_outcomes_consumer.py#L135-L142

Potential issue: The Python CLI in `accepted_outcomes_consumer.py` was updated to accept
`--health-check` options like `commit-progress` and `partition-stall`, along with
`--health-check-file`. However, the corresponding Rust implementation in
`rust_snuba/src/accepted_outcomes_consumer.rs` does not use these parameters, as
indicated by the `_health_check` and `_health_check_file` variable names. As a result,
no health check logic is executed and no health file is created. This will cause
Kubernetes liveness probes to fail for deployments using these new flags, leading to
repeated pod restarts.

Drop redundant health-file state, saturate idle-poll counters, and use checked SystemTime adds so long-running consumers cannot panic on overflow.
Track stable there for CI, Docker, and local cargo. Drop the extra rustup install step and Makefile +stable fmt override. Satisfy current-stable clippy.
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.

3 participants