Repository navigation
fix(source-control): stop Forgejo status refresh from scanning every pull request - #12223
Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a localized one-line Forgejo bug fix that filters pull-request listings server-side, reducing unnecessary pagination while preserving the existing client-side filtering behavior. It introduces no schema, deployment, default-setting, or static-analysis changes. Notes:
You can add or adjust custom eligibility rules. Learn more. |
e657d8d to
8dae589
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to The branch filter is encoded and retains the compatibility fallback; no merge-blocking issue remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1
✨ Finishing Touches
Comment |
|
Confirming this on self-hosted Forgejo The repo has ~200 PRs. Two of them are huge merged PRs: a package store committed by mistake, then removed (~5.7M lines / ~31k files each). Forgejo computes From the server trace:
For us this is what raises the "Some requests are slow" toast when the window regains focus. |
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dismissing prior approval to re-evaluate 8dae589
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Confirming this from outside the PR: I have been running this patch in a fork build since 2026-09-18, cherry-picked unchanged, against a self-hosted Forgejo. Three repositories there, the busiest with 126 pull requests tracked locally — exactly the "real pull request history" case, since that is what the old loop had to page through to answer a single branch. Two weeks of daily use, One thing I cannot report: the before/after on my own instance. I took the patch the day after this PR was opened, so I never ran the unfiltered loop against that Forgejo and have no timing to compare. What I can say is that Written with Claude Opus 5 (1M context) in T3 Code. |
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
First: forgive me for pasting a mostly-agent written comment. I'm not a frequent GitHub-participator, so I'm outside my comfort zone here. I wanted to try to help with T3 Code, as it's helping me out so much. Confirming this on self-hosted Forgejo 16.0.5 with nightly 0.0.46-nightly.20261008.2801. It caused real damage: on a 2-vCPU VPS, the unfiltered paging kept Forgejo at about one core, which helped drain the provider's CPU credits until the host was throttled to 20%. Measured 2026-10-08:
Two related things that would also help:
Archiving and settling threads (#16762) reduced the load for us. Quitting T3 was the only way to stop it completely. |
…pull request Pass head=<branch> to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered. Cherry-picked from upstream pingdotgg#12223, still open there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
@juliusmarminge @flamboh @maria-rcks Sorry for pinging you all but this is a super severe bug. It can lead to full CPU usage on FJ hosts for 15min+. |
…pull request Forgejo listed pull requests unfiltered and matched the head branch in JS, so a branch with one pull request or none walked the repository's entire history 50 rows at a time until a page came back empty. Status refreshes run that under the remote write lock, which is why vcs.refreshStatus hung past 15s on repositories with any real pull request history. Forgejo's pulls endpoint accepts a head parameter, so narrow server-side. The client-side branch match stays: a server too old for the filter ignores it and answers unfiltered. Signed-off-by: Loïs Postula <lois@postu.la>
Co-authored-by: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com>
8dae589 to
eeaceb2
Compare
Dismissing prior approval to re-evaluate eeaceb2
…lProvider.head-filter.test.ts
What Changed
Pass
head=<branch>to Forgejo's pulls endpoint instead of paging the whole repository and matching the branch client-side. The client-side match stays, since a server too old for the filter ignores it and answers unfiltered.Why
vcs.refreshStatushangs past 15s on any Forgejo or Gitea repository with real pull request history.findLatestPrForHeadContextasks for the branch's pull requests withlimit: 20. GitHub and GitLab narrow server-side; Forgejo did not, so it loopedwhile (results.length < limit)overpulls?state=all&limit=50&page=Nfiltering in JS. A branch has one pull request at most, so the loop only stopped on an empty page, walking every pull request in the repository. That sits insiderefreshStatus's remote write lock.headis documented onGET /repos/{owner}/{repo}/pulls. With it, a branch with one pull request costs two requests, a branch with none costs one.Introduced in #11436.
Checklist
Written with Claude Opus 5 in T3 Code.
rebased onto main at @juliusmarminge's request. updated the regression test for the extracted provider package.