Optimize search request handling with debouncing and AbortController#492
Conversation
✅ Deploy Preview for github-spy ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Review limit reached
More reviews will be available in 46 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 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR implements optimized search request handling to address excessive GitHub API calls during rapid typing. It adds ChangesDebounced Search with Request Cancellation
Sequence Diagram(s)sequenceDiagram
participant Component
participant fetchData
participant AbortController
participant Octokit
Component->>fetchData: call fetchData(username)
fetchData->>AbortController: abort previous controller
fetchData->>AbortController: create new controller
fetchData->>Octokit: GET /search/issues with signal
Note over Octokit: request in-flight
Component->>fetchData: call fetchData(new username)
fetchData->>AbortController: abort active controller
Octokit-->>fetchData: AbortError rejected
fetchData->>fetchData: detect AbortError, return early
fetchData->>Component: skip state updates
fetchData->>Component: finally: reset loading (if stale check passes)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/hooks/useGitHubData.ts (1)
104-115:⚠️ Potential issue | 🟠 Major | ⚡ Quick winEmpty-search transitions do not cancel the active request.
The new abort path only runs after the
!username.trim()/rateLimitedguard. WhenTracker.tsxclears the debounced username and suppresses the next fetch, the previous controller stays active, so that stale response can still pass therequestId/controller checks and repopulate state after the input is blank. Abort the current controller before this guard, or expose an explicit cancel/reset path for empty searches.Suggested minimal fix
- if (!octokit || !username.trim() || rateLimited) { - return; - } - - // Cancel any active in-flight request before triggering a new one if (abortControllerRef.current) { abortControllerRef.current.abort(); } + + if (!octokit || !username.trim() || rateLimited) { + return; + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hooks/useGitHubData.ts` around lines 104 - 115, The guard in useGitHubData currently returns before aborting an in-flight request, so clearing the debounced username can leave a previous request active; move or duplicate the abort logic so abortControllerRef.current?.abort() runs before the early-return (i.e., before checking !username.trim() || rateLimited), or add an explicit cancel/reset path that calls abortControllerRef.current.abort(), clears abortControllerRef.current, and increments/invalidates requestId when username becomes empty; update references to abortControllerRef and requestId in the hook (where controller is created and assigned) to ensure stale responses cannot repopulate state after an empty search.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/Tracker/Tracker.tsx`:
- Around line 105-109: handleSubmit currently both sets state (setPage,
setDebouncedUsername) and calls fetchData directly, causing duplicate requests;
remove the direct fetchData(username, 1, ROWS_PER_PAGE) call and instead drive
the effect that performs fetching from changes to debouncedUsername/page by
introducing a submit counter (e.g., submitCount state and setSubmitCount(c =>
c+1)) that the effect also depends on so the button can force refresh the same
username/page without calling fetchData manually; update the effect to include
submitCount alongside debouncedUsername and page and call fetchData from there.
---
Outside diff comments:
In `@src/hooks/useGitHubData.ts`:
- Around line 104-115: The guard in useGitHubData currently returns before
aborting an in-flight request, so clearing the debounced username can leave a
previous request active; move or duplicate the abort logic so
abortControllerRef.current?.abort() runs before the early-return (i.e., before
checking !username.trim() || rateLimited), or add an explicit cancel/reset path
that calls abortControllerRef.current.abort(), clears
abortControllerRef.current, and increments/invalidates requestId when username
becomes empty; update references to abortControllerRef and requestId in the hook
(where controller is created and assigned) to ensure stale responses cannot
repopulate state after an empty search.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 03e1e069-06d3-48aa-abc0-3bc200419c02
📒 Files selected for processing (2)
src/hooks/useGitHubData.tssrc/pages/Tracker/Tracker.tsx
| const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => { | ||
| e.preventDefault(); | ||
| setPage(0); | ||
| setDebouncedUsername(username); | ||
| fetchData(username, 1, ROWS_PER_PAGE); |
There was a problem hiding this comment.
Submit still triggers the same search twice.
Updating debouncedUsername already schedules the effect-based fetch. The extra fetchData(...) here sends a second identical request whenever the submitted username differs from the current debounced value or page resets, so the hook immediately aborts one of the two calls. Keep a single trigger path here; if the button must refresh the same username/page, drive the effect with a submit counter instead of calling fetchData directly.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pages/Tracker/Tracker.tsx` around lines 105 - 109, handleSubmit currently
both sets state (setPage, setDebouncedUsername) and calls fetchData directly,
causing duplicate requests; remove the direct fetchData(username, 1,
ROWS_PER_PAGE) call and instead drive the effect that performs fetching from
changes to debouncedUsername/page by introducing a submit counter (e.g.,
submitCount state and setSubmitCount(c => c+1)) that the effect also depends on
so the button can force refresh the same username/page without calling fetchData
manually; update the effect to include submitCount alongside debouncedUsername
and page and call fetchData from there.
|
@mehul-m-prajapati |
|
🎉🎉 Thank you for your contribution! Your PR #492 has been merged! 🎉🎉 |
Related Issue
Description
Optimized the GitHub tracker search request handling to prevent unnecessary API consumption, minimize hitting GitHub rate limits, and eliminate flickering or out-of-order UI updates:
500msdebounce timer for theGitHub Usernameinput inTracker.tsxso that requests are only fired after the user pauses typing. Clicking "Fetch Data" or submitting the form sets the debounced value immediately to trigger the request without double-fetching.AbortControllerinsideuseGitHubData.tsthat aborts any active in-flight requests immediately when a new fetch is initiated.AbortSignalto the Octokit request options (request: { signal }), allowing clean request aborts at the HTTP request layer.How Has This Been Tested?
npm run buildlocally to verify that all 3,015 modules build and compile into production assets successfully with no TypeScript compiler errors.Type of Change
Summary by CodeRabbit
Release Notes
Bug Fixes
Performance