-
Notifications
You must be signed in to change notification settings - Fork 289
Open
Description
Summary
The polling implementation in useBoard.ts uses recursive setTimeout without proper cleanup, causing memory leaks and zombie intervals.
Affected Files
src/hooks/useBoard.ts(lines 286-325)src/hooks/useCraps.ts(similar pattern)
Problem
// Current problematic pattern
const poll = async () => {
// ... fetch logic
timeoutRef.current = setTimeout(poll, POLL_INTERVAL);
};
useEffect(() => {
poll();
return () => clearTimeout(timeoutRef.current); // May not clear properly
}, []);Issues:
- Recursive setTimeout can create zombie intervals on hot reload
- Cleanup in useEffect may not properly clear pending async operations
- No AbortController for in-flight requests
Impact
- Memory grows over time
- Multiple polling loops after hot reloads
- Degraded performance after extended use
Proposed Fix
useEffect(() => {
const controller = new AbortController();
let timeoutId: NodeJS.Timeout;
let isMounted = true;
const poll = async () => {
if (!isMounted) return;
try {
await fetchData({ signal: controller.signal });
} finally {
if (isMounted) {
timeoutId = setTimeout(poll, POLL_INTERVAL);
}
}
};
poll();
return () => {
isMounted = false;
controller.abort();
clearTimeout(timeoutId);
};
}, []);Labels
bug, high-priority
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels