Skip to content

fix: back off repeated GitHub CLI reads - #6345

Merged
atomantic merged 3 commits into
mainfrom
claim/issue-6343
Sep 5, 2026
Merged

fix: back off repeated GitHub CLI reads#6345
atomantic merged 3 commits into
mainfrom
claim/issue-6343

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

  • apply consecutive-failure backoff to periodic GitHub read paths in PR, issue, blocked-issue, branch, and update reconciliation
  • preserve explicit/manual update checks and mutating GitHub calls as immediate operations
  • guard per-process backoff outcome settlement across child lifecycle events

Closes #6343

Validation

  • npm test -- services/github.test.js services/branchReconcile.test.js services/updateChecker.test.js services/prWatcher.test.js services/issueReconcile.test.js services/blockedIssueReconcile.test.js services/taskDataInputs.test.js — 418 passed
  • npm test — 39,846 passed, 35 skipped

Review gate

  • Required local agy --effort medium reviewer found and the fix was applied for one low-severity child lifecycle finding.
  • Follow-up invocation timed out after 5 minutes without a verdict; review status is review-blocked. Per delivery policy this PR is left open for cold pickup and is not being merged.

…y tick

A gh blip during a real incident let branch-reconcile and updateChecker
re-fire the same 60s-timeout `gh pr list` / release-check call for every
managed repo on every scheduler tick with no cooldown, piling up
concurrent gh processes while gh was already struggling (confirmed in
PM2 logs: repeated timeouts across PortOS, gradient-play, and BookLoom
within a few minutes). ensureForgeReachable's 60s health probe doesn't
catch this because it's a separate, cheaper call that can pass while the
heavier read still hangs.

Add an opt-in `backoffKey` to execGh() with exponential backoff per key,
cleared on success. Mutating/one-off gh calls are unaffected (they don't
pass a key). Wired into branchReconcile's PR-list read and
updateChecker's release check — the two call sites that hit this in the
observed incident. Filed #6343 to extend it to the remaining periodic
gh readers (prWatcher, issueReconcile, blockedIssueReconcile).
The backoff added in the previous commit is keyed the same whether
checkForUpdate() is called by the unattended 30-min scheduler or by a
user clicking "check for updates" (POST /api/update/check). Without this,
a cooldown armed by the background poller's own failure would silently
reject an explicit user-triggered check for up to 15 minutes with no real
attempt. checkForUpdate() now takes { manual: true } to skip the
backoffKey; the route passes it, the scheduler doesn't.
@atomantic

Copy link
Copy Markdown
Owner Author

Required code review was not completed before publication. This PR is intentionally left open and will not be merged until the required review completes.

@atomantic
atomantic merged commit 0f42e34 into main Sep 5, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-6343 branch September 5, 2026 22:54
atomantic added a commit that referenced this pull request Sep 5, 2026
updateChecker's 30-min scheduler interval always exceeds the 15-min
backoff cap #6345 hardcoded, so the cooldown from a failed release
check expires before every subsequent tick and never actually
suppresses a retry -- a silent no-op for its only production caller.

execGh now takes an optional backoffMaxMs override; branch-reconcile
and the other pollers keep the default (appropriate for their much
faster tick rate), and updateChecker passes 3x its own interval so
repeated failures actually widen the gap between real attempts.
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.

Extend execGh consecutive-failure backoff to remaining periodic gh readers

1 participant