Skip to content

Memory Leak in SetInterval#657

Open
annrose2277-glitch wants to merge 1 commit into
GitMetricsLab:mainfrom
annrose2277-glitch:get
Open

Memory Leak in SetInterval#657
annrose2277-glitch wants to merge 1 commit into
GitMetricsLab:mainfrom
annrose2277-glitch:get

Conversation

@annrose2277-glitch
Copy link
Copy Markdown

@annrose2277-glitch annrose2277-glitch commented Jun 1, 2026

Related Issue


Description

Resolved a memory leak and potential stale closure bug in ActivityFeed.tsx. The setInterval function was relying on fetchEvents, but the function was missing from the useEffect dependency array. Refactored the fetch logic so that intervals are properly cleared and recreated without causing multiple API calls to stack up in the background.


How Has This Been Tested?

  • Ran the development server locally.
  • Monitored the network tab to ensure API calls are strictly firing every 30 seconds.
  • Navigated between different user profiles to ensure the useEffect cleanup function properly destroys the old interval before starting a new one.

Type of Change

  • Bug fix
  • New feature
  • Code style update
  • Breaking change
  • Documentation update

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling for GitHub events fetching—the Activity Feed now properly handles failed requests and ensures event data is reliably validated and displayed.

@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 1, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit a341296
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a1d0e352ac0b30008499fa3
😎 Deploy Preview https://deploy-preview-657--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

ActivityFeed's GitHub events fetch now validates HTTP response status before consuming the response body. On non-OK responses it clears events and stops loading early. Parsed JSON is normalized to an array, replacing the previous behavior of accepting non-array payloads.

Changes

GitHub Events Fetch Robustness

Layer / File(s) Summary
HTTP Response Validation and JSON Normalization
src/components/ActivityFeed.tsx
The fetch handler checks res.ok to detect HTTP errors, clears events and stops loading on failures, and normalizes parsed JSON to an array via Array.isArray(data) ? data : [], preventing non-array payloads from being set.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

level:intermediate, quality:clean

Poem

🐰 A fetch with grace, now checks the way,
No broken JSON ruins the day!
Arrays held tight, no leaks through the cracks—
Safe, solid data on its tracks. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR description claims to have fixed the memory leak by refactoring fetch logic, but the actual code changes show only HTTP response handling and JSON normalization, with no evidence of fixing the core dependency array issue mentioned in #646. Verify that the code changes actually address the missing fetchEvents dependency array issue from #646, or clarify if this PR only partially addresses the bug and requires follow-up work.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive The code changes (HTTP response status checking and JSON normalization) appear related to ActivityFeed.tsx but do not match the stated objective of fixing the setInterval dependency array issue described in #646. Clarify whether the HTTP response handling and JSON normalization changes are necessary parts of fixing the memory leak issue, or if they are separate improvements that should be addressed in a different PR.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Memory Leak in SetInterval' directly matches the main change in the pull request, which addresses a memory leak issue caused by missing dependency in setInterval.
Description check ✅ Passed The PR description includes all required template sections: Related Issue (#646), Description of the fix, How Has This Been Tested, and Type of Change (Bug fix) is marked.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/ActivityFeed.tsx (1)

28-57: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prevent stale async GitHub event responses from overwriting state

useEffect cleanup only clears the polling interval; it doesn’t cancel in-flight fetch calls or guard against older responses. When username changes, a slower previous request can still resolve and call setEvents/setLoading with stale data.

Suggested fix
 useEffect(() => {
+  const controller = new AbortController();
+
   const fetchEvents = async () => {
     try {
       setLoading(true);

       const res = await fetch(
-        `https://api.github.com/users/${username}/events`
+        `https://api.github.com/users/${username}/events`,
+        { signal: controller.signal }
       );

       if (!res.ok) {
         setEvents([]);
         setLoading(false);
         return;
       }

       const data = await res.json();
+      if (controller.signal.aborted) return;
       setEvents(Array.isArray(data) ? data : []);
       setLoading(false);
     } catch (err) {
+      if ((err as DOMException).name === "AbortError") return;
       console.error(err);
+      setEvents([]);
       setLoading(false);
     }
   };

   fetchEvents();

   const interval = setInterval(fetchEvents, 30000);
-  return () => clearInterval(interval);
+  return () => {
+    clearInterval(interval);
+    controller.abort();
+  };
 }, [username]);
🤖 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/components/ActivityFeed.tsx` around lines 28 - 57, The effect's
fetchEvents can let slow responses overwrite state when username changes; modify
it to create an AbortController for each fetch and pass controller.signal to
fetch inside fetchEvents, catch and ignore abort errors, and call
controller.abort() in the useEffect cleanup (in addition to clearInterval) so
in-flight requests are cancelled when username changes; also optionally capture
the current username in a local variable inside the effect (e.g., const current
= username) and before calling setEvents/setLoading verify the username still
matches to further guard against stale responses.
🤖 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.

Outside diff comments:
In `@src/components/ActivityFeed.tsx`:
- Around line 28-57: The effect's fetchEvents can let slow responses overwrite
state when username changes; modify it to create an AbortController for each
fetch and pass controller.signal to fetch inside fetchEvents, catch and ignore
abort errors, and call controller.abort() in the useEffect cleanup (in addition
to clearInterval) so in-flight requests are cancelled when username changes;
also optionally capture the current username in a local variable inside the
effect (e.g., const current = username) and before calling setEvents/setLoading
verify the username still matches to further guard against stale responses.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84670e5d-ea6a-488b-90ac-2b8365574265

📥 Commits

Reviewing files that changed from the base of the PR and between 53f820b and a341296.

📒 Files selected for processing (1)
  • src/components/ActivityFeed.tsx

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: Memory Leak in SetInterval

1 participant