Skip to content

Commit e730b57

Browse files
matej21claude
andcommitted
fix(git-poll): stop the PR/CI poller burning the GitHub API budget
Measured on a 94-project workspace with 11 projects visible: the daemon was spawning 108-300 `gh` invocations per minute across 34 repositories, or roughly 4,600-9,300 REST requests per hour against a 5,000/hour limit (plus 2,000-3,000 GraphQL). The limit was exhausted and every PR/CI badge was quietly getting 403s. Five compounding causes, all fixed here: 1. Scope. `gh` followed the *streaming* set — visible projects plus any owning a terminal a remote client subscribed to. Clients subscribe to every terminal in the daemon's state, not just what they render, so a project merely owning a terminal landed on the responsive GitHub cadence: 34 repos polled to render 11 badges. `gh` now follows visibility only; local git status keeps the wider set. 2. Cadence. One repo with running CI flipped a global flag that put all 34 onto the 15s cadence. Cadence is now per project, via `GithubPollSchedule`. 3. Redundancy. Checks on a commit only move while something is running, but every poll re-fetched them regardless. `fetch_ci_checks` now takes the commit a settled result describes and skips the request while the branch still points at it — a repo parked on `main` costs one local ref read instead of two REST calls. Settled results are revalidated every ~10min so a re-run is still noticed. 4. Overlap. A pass ran projects strictly sequentially (~250ms each, so ~17s for 34 repos) while being re-spawned unconditionally every cadence tick — passes stacked, and the same repo was observed fetched twice in the same second. Passes now run 4-wide (matching the process bus's Poll lane) and never start while one is in flight. 5. Refusals. Nothing recognised a rate-limit response, so an exhausted budget changed nothing about the request rate. A refusal now parks all `gh` traffic with a doubling 60s-30min backoff, and is no longer cached as "this project has no PR". Also drops the CI cache on every local commit: checks belong to the last *pushed* commit, which a local commit doesn't move, so that eviction only blanked the badge and forced a refetch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfU7oDTtKEaQ9vG7Y6fquX
1 parent 50a6a1f commit e730b57

5 files changed

Lines changed: 938 additions & 500 deletions

File tree

0 commit comments

Comments
 (0)