Skip to content

Forgejo provider pages through every PR to find a branch's PR (about 150k API calls a day) #41

Description

@pseudoseed

Problem

The Forgejo source-control provider finds the pull request for a branch by paging through every pull request in the repository until it finds one whose head.ref matches. It does this on every refresh, for every thread.

The loop in the built app:

for (let page = 1; results.length < limit; page++) {
  const items = yield* request({
    ...input,
    path: `${repositoryPath(repo.repository)}/pulls?state=${...}&sort=recentupdate&limit=50&page=${page}`
  }, ArraySchema(ForgejoPullRequestSchema));
  for (const item of items) {
    if (item.head.ref !== branch || ...) continue;
    ...

For a branch that has no PR, it reads every page. On a repository with about 2,000 PRs, that is 40 requests.

Measured impact (one self-hosted Forgejo 16 instance, one desktop client)

  • 153,134 GET /repos/{owner}/{repo}/pulls?state=all&sort=recentupdate&limit=50&page=N requests in one day, from one machine running the app.
  • 3,000-3,900 requests per hour while the app is open.
  • Each request takes about 2 s on the server. That keeps the server busy with roughly 1.7 of these requests at any moment, which slows the API for everything else, including CI.

Suggested fix

  1. If the thread already knows its PR number, fetch that PR directly: GET /repos/{owner}/{repo}/pulls/{index}.
  2. Otherwise, look the PR up by branch in one call: GET /repos/{owner}/{repo}/pulls/{base}/{head} (Forgejo/Gitea "get a pull request by base and head").
  3. If a list is still needed, stop at the first match, cap the number of pages, and cache "no PR for this branch" for a few minutes.
  4. Poll idle threads less often.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions