Skip to content

⚡ perf: deduplicate concurrent GitHub API requests#489

Closed
is0692vs wants to merge 1 commit into
mainfrom
perf-og-api-dedupe-6185246957405465171
Closed

⚡ perf: deduplicate concurrent GitHub API requests#489
is0692vs wants to merge 1 commit into
mainfrom
perf-og-api-dedupe-6185246957405465171

Conversation

@is0692vs

@is0692vs is0692vs commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

💡 What: Implemented an in-memory Map to cache in-flight promises.
🎯 Why: To prevent redundant identical fetches and avoid rate limits.
📊 Measured Improvement: Verified via unit tests that concurrent requests are deduplicated into a single fetch.


PR created automatically by Jules for task 6185246957405465171 started by @is0692vs

Greptile Summary

This PR adds in-flight deduplication for OG GitHub API requests.

  • Adds a module-level Map for active username fetches.
  • Reuses the same GitHub fetch promise for concurrent matching requests.
  • Adds a unit test for concurrent request deduplication.

Confidence Score: 4/5

The OG dedupe path needs a fix before merging.

  • Successful concurrent requests are deduplicated as intended.
  • A temporary GitHub non-OK response is shared with every waiting caller.
  • Waiting callers can receive fallback OG images instead of fresh profile data.

src/app/api/og/[username]/route.tsx

Important Files Changed

Filename Overview
src/app/api/og/[username]/route.tsx Adds in-flight GitHub profile fetch deduplication for the OG route, with failure results now shared across concurrent callers.
src/app/api/og/[username]/route.test.ts Adds coverage that identical concurrent OG requests call fetch only once.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant R1 as Request 1
    participant R2 as Request 2
    participant M as inflightRequests
    participant GH as GitHub API

    R1->>M: lookup username
    M-->>R1: miss
    R1->>M: store fetch promise
    R1->>GH: fetch profile
    R2->>M: lookup username
    M-->>R2: same promise
    GH-->>R1: non-OK response
    R1->>M: delete username
    M-->>R1: null result
    M-->>R2: null result
    R1-->>R1: render fallback OG image
    R2-->>R2: render fallback OG image
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant R1 as Request 1
    participant R2 as Request 2
    participant M as inflightRequests
    participant GH as GitHub API

    R1->>M: lookup username
    M-->>R1: miss
    R1->>M: store fetch promise
    R1->>GH: fetch profile
    R2->>M: lookup username
    M-->>R2: same promise
    GH-->>R1: non-OK response
    R1->>M: delete username
    M-->>R1: null result
    M-->>R2: null result
    R1-->>R1: render fallback OG image
    R2-->>R2: render fallback OG image
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
src/app/api/og/[username]/route.tsx:61-62
**Shared Failure Result**

When the first in-flight GitHub request for a username returns a temporary non-OK response, this promise resolves to `null` and every concurrent caller renders the fallback OG image. Before this change, those callers fetched independently, so a later concurrent request could still return real profile data instead of sharing the first transient failure.

Reviews (1): Last reviewed commit: "perf: deduplicate concurrent GitHub API ..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
github-user-summary Ignored Ignored Jul 17, 2026 6:41am

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@dosubot dosubot Bot added the enhancement New feature or request label Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@is0692vs, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 53 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 94f7409a-42e7-4d48-bb3e-482f95afd9a4

📥 Commits

Reviewing files that changed from the base of the PR and between 0a9a1e0 and e8cff27.

📒 Files selected for processing (2)
  • src/app/api/og/[username]/route.test.ts
  • src/app/api/og/[username]/route.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf-og-api-dedupe-6185246957405465171

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a request-deduplication mechanism for fetching GitHub user profiles in the OG image route using an inflightRequests map, and adds a corresponding integration test to verify concurrent request deduping. The feedback recommends adding explicit return types to the anonymous async function in the route handler and the mock fetch implementation in the test file to improve type safety.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

const data = await res.json();
let fetchPromise = inflightRequests.get(username);
if (!fetchPromise) {
fetchPromise = (async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add an explicit return type to the anonymous async function to ensure type safety and adhere to the TypeScript guidelines.

Suggested change
fetchPromise = (async () => {
fetchPromise = (async (): Promise<GitHubProfile | null> => {
References
  1. Maintain explicit return types for functions in TypeScript to ensure type safety and API clarity.

Comment on lines +154 to +160
const mockFetch = vi.spyOn(global, "fetch").mockImplementation(() => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(new Response(JSON.stringify({ name: "Valid User" }), { status: 200 }));
}, 50);
});
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The mock implementation returns a Promise but is not defined as an async function, and it lacks an explicit return type. To align with the repository's TypeScript guidelines, please update it to be an async function with an explicit return type.

Suggested change
const mockFetch = vi.spyOn(global, "fetch").mockImplementation(() => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(new Response(JSON.stringify({ name: "Valid User" }), { status: 200 }));
}, 50);
});
});
const mockFetch = vi.spyOn(global, "fetch").mockImplementation(async (): Promise<Response> => {
return new Promise<Response>((resolve) => {
setTimeout(() => {
resolve(new Response(JSON.stringify({ name: "Valid User" }), { status: 200 }));
}, 50);
});
});
References
  1. In TypeScript, ensure functions and mock implementations have explicit return types and use async functions for mocks returning Promises to maintain type safety and readability.

Comment on lines +61 to +62
}
return null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Shared Failure Result

When the first in-flight GitHub request for a username returns a temporary non-OK response, this promise resolves to null and every concurrent caller renders the fallback OG image. Before this change, those callers fetched independently, so a later concurrent request could still return real profile data instead of sharing the first transient failure.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/api/og/[username]/route.tsx
Line: 61-62

Comment:
**Shared Failure Result**

When the first in-flight GitHub request for a username returns a temporary non-OK response, this promise resolves to `null` and every concurrent caller renders the fallback OG image. Before this change, those callers fetched independently, so a later concurrent request could still return real profile data instead of sharing the first transient failure.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@is0692vs

Copy link
Copy Markdown
Contributor Author

Superseded by #495, which changes the same OG route and tests with a completed 5/5 review.

@is0692vs is0692vs closed this Jul 18, 2026
@is0692vs
is0692vs deleted the perf-og-api-dedupe-6185246957405465171 branch July 18, 2026 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant