Skip to content

⚡ Optimize GitHub fetchActivity early-exit concurrency#355

Open
is0692vs wants to merge 1 commit into
mainfrom
perf/github-fetch-allsettled-729205816111143846
Open

⚡ Optimize GitHub fetchActivity early-exit concurrency#355
is0692vs wants to merge 1 commit into
mainfrom
perf/github-fetch-allsettled-729205816111143846

Conversation

@is0692vs

@is0692vs is0692vs commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

💡 What: Replaced the sequential for...of loop awaiting promises with a fail-fast, concurrent structure utilizing Promise.race([p, criticalErrorPromise]).
🎯 Why: The previous logic awaited promises in sequence. While Promise.allSettled was an alternative, it caused severe regressions because it waited for all promises, even when early exit logic (events.length < 100) or critical errors like RateLimit were met. The criticalErrorPromise allows us to immediately break and short-circuit the execution while still processing concurrent resolves sequentially for safe list building.
📊 Measured Improvement:

  • Late Error simulation: ~10ms execution vs unoptimized full timeouts.
  • Early Error simulation (Rate limit fast): ~9.8ms execution down from ~501ms in sequential iterations.
  • Baseline success path speed remains identical (~9.7ms).

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

Greptile Summary

fetchActivity で全ページリクエストを並行起動し、Promise.race([p, criticalErrorPromise]) を使って UserNotFoundError / RateLimitError 発生時にループを即座に脱出できる fail-fast 構造に変更した PR です。その他の変更はコードフォーマット(行折り返し)のみです。

  • criticalRejectlet criticalReject: (reason?: unknown) => void; と宣言しているが、strict: true の TypeScript はコールバック内の同期代入を認識できないため TS2454 コンパイルエラーが発生する可能性がある。
  • promises.forEach の抑制ハンドラーが、ループで現在処理中のページのエラーも独立してキャッチするため、非クリティカルエラー時に二重ログが起きる可能性がある(機能的な影響なし、元のコードからの継続動作)。

Confidence Score: 3/5

criticalReject の宣言方法に起因するコンパイルエラーが解消されるまでマージは推奨しません。

let criticalReject: (reason?: unknown) => void という宣言は、strict: true が有効な TypeScript では Promise コンストラクター内の同期代入を制御フロー解析で追えないため TS2454 エラーになる可能性が高く、ビルドが壊れるリスクがあります。ロジック自体(Promise.race による fail-fast)は意図どおりに動作しますが、このコンパイル上の文題が解消されないと安全にマージできません。

src/lib/github.ts の fetchActivity 関数内の criticalReject 宣言箇所(749行目付近)を重点的に確認してください。

Important Files Changed

Filename Overview
src/lib/github.ts fetchActivityfor...of ループを Promise.race([p, criticalErrorPromise]) による fail-fast 並行処理に置き換え。残りの変更はコードフォーマットのみ。criticalReject の確定代入アサーション漏れにより strict: true 下でコンパイルエラーが発生する可能性あり。

Sequence Diagram

sequenceDiagram
    participant ForLoop as fetchActivity
    participant Race as Promise.race
    participant P1 as Page1 Request
    participant P2 as Page2 Request
    participant CEP as criticalErrorPromise

    par Concurrent Launch
        P1-->>P1: fetch page 1
        P2-->>P2: fetch page 2
    end

    Note over P2: RateLimitError occurs
    P2->>CEP: criticalReject(error)
    P2-->>P2: throw error

    ForLoop->>Race: await Promise.race([p1, CEP])
    CEP-->>Race: reject with RateLimitError
    Race-->>ForLoop: throw RateLimitError
    ForLoop-->>ForLoop: "catch rethrows -> early exit"
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
src/lib/github.ts:749
確定代入アサーション `!` を使って宣言することで、`strict: true` 下の TS2454 コンパイルエラーを回避できます。

```suggestion
  let criticalReject!: (reason?: unknown) => void;
```

### Issue 2 of 2
src/lib/github.ts:771-778
**ループで処理中のページのエラーも抑制ハンドラーでキャッチされる**

`promises.forEach` でアタッチされた `.catch` は、ループ内で `await Promise.race([p, criticalErrorPromise])` が既にキャッチ処理中の「現在のページ」の `p` にも独立して発火します。非クリティカルエラーが現在処理中のページで起きた場合、ループの `catch` ブロックで `break` しつつ、forEach ハンドラー側でも `logger.error` が呼ばれる二重ログが発生します。機能的なバグではなく元のコードからの継続動作ですが、ループが既にエラーを処理済みにもかかわらずログが出るため混乱の元になります。

Reviews (1): Last reviewed commit: "perf: optimize concurrent fetching early..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

…vity

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 Jun 6, 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 Jun 6, 2026 3:23am

@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 Jun 6, 2026
@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

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

More reviews will be available in 49 minutes and 44 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 74c5bfe0-f5c2-4dfc-b932-fbd5288c67db

📥 Commits

Reviewing files that changed from the base of the PR and between 4e9c001 and e8a09f8.

📒 Files selected for processing (1)
  • src/lib/github.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/github-fetch-allsettled-729205816111143846

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 and usage tips.

@codecov

codecov Bot commented Jun 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.00000% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/lib/github.ts 92.00% 0 Missing and 4 partials ⚠️

📢 Thoughts on this report? Let us know!

@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 primarily introduces code formatting and style consistency updates across src/lib/github.ts. It also implements a fast-fail mechanism in fetchActivity using Promise.race to immediately propagate critical errors, such as UserNotFoundError or RateLimitError, during concurrent page fetches. As there are no review comments provided, I have no feedback to offer.

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.

Comment thread src/lib/github.ts
const pages = [1, 2, 3];
const allEvents: GitHubEvent[] = [];

let criticalReject: (reason?: unknown) => void;

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 確定代入アサーション ! を使って宣言することで、strict: true 下の TS2454 コンパイルエラーを回避できます。

Suggested change
let criticalReject: (reason?: unknown) => void;
let criticalReject!: (reason?: unknown) => void;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/github.ts
Line: 749

Comment:
確定代入アサーション `!` を使って宣言することで、`strict: true` 下の TS2454 コンパイルエラーを回避できます。

```suggestion
  let criticalReject!: (reason?: unknown) => void;
```

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!

Comment thread src/lib/github.ts
Comment on lines 771 to +778
// Suppress unhandled promise rejections for subsequent pages if we break early or throw
promises.forEach((p) => p.catch((e) => logger.error("Event fetch promise rejected:", e)));
promises.forEach((p) =>
p.catch((e) => {
if (!(e instanceof UserNotFoundError) && !(e instanceof RateLimitError)) {
logger.error("Event fetch promise rejected:", e);
}
}),
);

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.

P2 ループで処理中のページのエラーも抑制ハンドラーでキャッチされる

promises.forEach でアタッチされた .catch は、ループ内で await Promise.race([p, criticalErrorPromise]) が既にキャッチ処理中の「現在のページ」の p にも独立して発火します。非クリティカルエラーが現在処理中のページで起きた場合、ループの catch ブロックで break しつつ、forEach ハンドラー側でも logger.error が呼ばれる二重ログが発生します。機能的なバグではなく元のコードからの継続動作ですが、ループが既にエラーを処理済みにもかかわらずログが出るため混乱の元になります。

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/github.ts
Line: 771-778

Comment:
**ループで処理中のページのエラーも抑制ハンドラーでキャッチされる**

`promises.forEach` でアタッチされた `.catch` は、ループ内で `await Promise.race([p, criticalErrorPromise])` が既にキャッチ処理中の「現在のページ」の `p` にも独立して発火します。非クリティカルエラーが現在処理中のページで起きた場合、ループの `catch` ブロックで `break` しつつ、forEach ハンドラー側でも `logger.error` が呼ばれる二重ログが発生します。機能的なバグではなく元のコードからの継続動作ですが、ループが既にエラーを処理済みにもかかわらずログが出るため混乱の元になります。

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

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/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant