fix(performance): fetch GitHub commits concurrently to prevent serverless timeouts - #3174
fix(performance): fetch GitHub commits concurrently to prevent serverless timeouts#3174nyxsky404 wants to merge 8 commits into
Conversation
GSSoC Label Checklist 🏷️@Priyanshu-byte-coder — please apply the appropriate labels before merging: Difficulty (pick one):
Quality (optional):
Validation (required to score):
|
|
Good instinct on the serverless timeout, but firing pages 2..N as fully-parallel |
…e limit GitHub recommends against firing concurrent requests for a single user token, since Search has a low secondary rate limit. The previous implementation fired up to 9 pages via a single Promise.all, risking a secondary-rate-limit block. Batch remaining pages through a bounded pool of 3 concurrent requests instead, keeping the timeout mitigation while staying within GitHub's guidance. Rate-limited pages continue to contribute no items, falling back to whatever partial results were already fetched, as intended.
6fd7faf to
d99c9f9
Compare
|
Updated:
|
There was a problem hiding this comment.
Pull request overview
Refactors the GitHub commit Search API pagination in fetchContributionsForAccount to reduce latency and mitigate serverless/edge timeouts by fetching subsequent pages with bounded concurrency.
Changes:
- Adds a bounded concurrency approach for fetching additional GitHub Search pages after the first page determines
total_count. - Introduces
PAGE_FETCH_CONCURRENCYto limit parallelism and reduce likelihood of triggering secondary rate limits. - Restructures pagination from a sequential loop to batched
Promise.all()calls.
Suppressed comments (1)
src/app/api/metrics/contributions/route.ts:225
- When a later page is rate-limited (or returns fewer than 100 items), the code currently keeps requesting subsequent batches. That can exacerbate secondary rate limits and adds unnecessary work; after a rate-limit response (or the first short page) you should stop issuing further page requests and just return the partial results collected so far.
for (let i = 0; i < remainingPages.length; i += PAGE_FETCH_CONCURRENCY) {
const batch = remainingPages.slice(i, i + PAGE_FETCH_CONCURRENCY);
const batchResults = await Promise.all(batch.map((p) => fetchPage(p)));
for (const res of batchResults) {
// Rate-limited pages intentionally contribute no items; the
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@Priyanshu-byte-coder Please review, repo is already stared by me |
This PR refactors the GitHub Search API pagination in
fetchContributionsForAccount. Previously, the route fetched up to 10 pages sequentially in awhileloop, which could take up to 20 seconds for highly active users and frequently caused 504 Gateway Timeouts on Vercel's edge/serverless architecture. The new implementation fetches the first page to determine thetotal_count, and then fetches the remaining required pages (up to 10 max) concurrently usingPromise.all(). This drastically reduces the total execution time while correctly handling secondary rate limit (HTTP 429/403) fallbacks. Fixes #3170.