Skip to content

fix(sessions): back off history passes when retained ingest is Blocked instead of re-driving a broken store every wake - #4573

Merged
ScriptedAlchemy merged 2 commits into
ScriptedAlchemy:masterfrom
spa5k:fix/blocked-ingest-backoff
Oct 27, 2026
Merged

ScriptedAlchemy merged 2 commits into
ScriptedAlchemy:masterfrom
spa5k:fix/blocked-ingest-backoff

Conversation

@spa5k

@spa5k spa5k commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Scheduler half of #4569. Related: #4481 (the registry.rs worker-hog load), #4564, #4567.

Problem

run_session_temporal_refresh_scheduler treated a Blocked historical-ingest outcome as warn-and-continue. Blocked is terminal per host (e.g. projection_store_corrupt, retryable=false upstream), so every wake re-ran a full pass that read the same permanently broken store before failing identically.

Measured on one machine over two days, against a corrupt 1.6 GB sessions.db:

  • 68× retained historical session ingest is blocked reason_code="claude:projection_store_corrupt,cursor:projection_store_corrupt" (plus 68× each across four host catch-up paths)
  • 9,241× native task held its worker for one poll past 100ms from registry.rs spawn sites — the re-driven passes are the CPU cost

Change

  • History passes back off exponentially when a pass reports Blocked: 1 min doubling, capped at 1 h. Projections keep their cadence; only the history pass is suppressed.
  • The first Blocked outcome logs one error-level event with the reason codes and the retry schedule; subsequent ones log a bounded warn with the attempt number.
  • Any pass that makes progress (or completes) resets the backoff, so a healed store returns to full cadence immediately.

The relational-store rebuild protocol (the real fix for a corrupt sessions.db) stays tracked in #4569 — this PR removes the unbounded re-drive cost, not the corruption.

Tests

tracedecay-session-runtime scheduler tests: 49/49 green (--features tracedecay-rusqlite-runtime/test-runtime; without the feature these tests fail on clean master too — cargo harness lacks the process runtime, CI runs the Bazel targets). cargo check clean.


Devin Review

A Blocked outcome (for example projection_store_corrupt, retryable=false
upstream) warned and continued, so every wake re-ran a full pass that
read the same permanently broken store before failing again — 9,241
worker-hog warnings over two days on one machine, on top of a corrupt
1.6 GB sessions.db re-read at full cadence.

History passes now back off exponentially, 1 min doubling to a 1 h cap;
the first Blocked outcome logs one error-level event with the reason
codes and the retry schedule, later ones a bounded warn. Any pass that
makes progress resets the backoff. Projections keep their cadence.

Scheduler half of ScriptedAlchemy#4569; the relational-store rebuild protocol stays
tracked there.
@changeset-bot

changeset-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: eac3bff

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

A pass where one provider advances while another stays blocked reports
Blocked { made_progress: true }; resetting the backoff on progress let
the blocked store be re-read at full wake cadence again. The backoff
now clears only on an outcome with no blocker.
@spa5k

spa5k commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

Addressed in the follow-up commit: a Blocked { made_progress: true } pass (one provider advancing, another blocked) no longer clears the backoff — it resets only on an outcome with no blocker, so the corrupt provider is re-read at most hourly while healthy providers keep projecting. Scheduler tests stay 49/49.

@ScriptedAlchemy
ScriptedAlchemy merged commit 96fe61b into ScriptedAlchemy:master Oct 27, 2026
17 of 19 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.

2 participants