Skip to content

fix(result-set): bound and clean up filter/sort render polls - #2025

Merged
openai0229 merged 4 commits into
OtterMind:mainfrom
Aias00:fix/2023-filtersort-poller-leak
Jul 24, 2026
Merged

fix(result-set): bound and clean up filter/sort render polls#2025
openai0229 merged 4 commits into
OtterMind:mainfrom
Aias00:fix/2023-filtersort-poller-leak

Conversation

@Aias00

@Aias00 Aias00 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Related issue

Closes #2023

Summary

useFilterAndSort polled VTable with setInterval(..., 100) until the
rendered CHAT2DB_ROW_NUMBER list changed, then clearInterval. If the
list never changed (empty result set, a filter yielding the same rows, or
the component unmounting mid-poll), the interval ran forever. The
timerId was a local variable inside each handler closure — there was no
ref and no unmount cleanup — so after unmount the interval kept firing and
called setState/table APIs on an unmounted component, leaking memory.
The same pattern appeared at four sites (lines 187/219/250/309).

Changes:

  • Add a pollTimerIdsRef that tracks active poll timers.
  • Add a pollUntilRowNumbersChange(before, onSettled) helper with a
    MAX_POLL_ITERATIONS cap (100 iterations x 100ms = 10s) so a poll
    cannot run forever when the row list never changes; each timer is
    registered and unregistered on settle/cap.
  • Add an unmount useEffect that clears every active timer.
  • Route all four inline poll sites (sort, filter clear-all, filter apply,
    clearAllFilters) through the helper.

The cap value (MAX_POLL_ITERATIONS = 100) is chosen generously: the
polls run every 100ms and VTable render settles in milliseconds, so 10s
is far above the normal settle time while still bounding the leak. It is
a single named constant and trivial to tune.

Affected surfaces

  • Frontend / Web
  • Backend / API / Storage
  • Database plugin / Driver
  • JCEF / Desktop packaging
  • CI / Build / Release
  • Documentation only

Verification

  • Commands and results:
    • npx tsc --noEmit -p chat2db-community-client/tsconfig.json — no errors reported for useFilterAndSort.tsx.
    • npx eslint src/blocks/SearchResult/components/ResultSetTable/hooks/useFilterAndSort.tsx — no errors.
    • Confirmed only one setInterval remains (the helper's) and all four call sites now call pollUntilRowNumbersChange (lines 224/250/275/328).
  • Manual verification: On an empty result set or a same-row filter, a poll now stops after the cap instead of running forever; navigating away mid-poll clears active timers via the unmount effect.
  • UI evidence: N/A

Risk and compatibility

  • Public API or stored data: N/A.
  • Database or driver compatibility: N/A.
  • Network, privacy, or security: N/A.
  • Community / Local / Pro boundary: N/A.
  • Backward compatibility: Polling behavior is unchanged in the normal case (settles, calls sortAfter/filterAfter, clears the timer). Only the previously-leaking paths are bounded and cleaned up.

Reviewer map

  • Start here: useFilterAndSort.tsx — new MAX_POLL_ITERATIONS constant (line 33), pollTimerIdsRef + pollUntilRowNumbersChange helper + unmount useEffect (lines 52-83), and the four call sites (224/250/275/328) replacing the inline setInterval blocks.
  • Failure condition: Intervals still leak on empty/same-row results or after unmount.
  • Rollback or disable path: Revert this single commit; behavior returns to the original (leaking) polls.

Contributor declaration

  • I linked the Issue that defines this change.
  • I tested the affected behavior and reported the actual results above.
  • I did not include credentials, private data, or generated build output.
  • I disclosed substantial AI assistance below, or this PR contains no substantial AI-generated code.

AI assistance: The fix, verification, and PR description were produced with Claude Code assistance.

useFilterAndSort polled VTable with setInterval(100ms) until the row
list changed, then clearInterval. If the list never changed (empty
result, same-row filter) or the component unmounted mid-poll, the
interval ran forever and fired setState on an unmounted component.
The timerId was a local with no ref and no unmount cleanup.

Add a pollTimerIdsRef, a pollUntilRowNumbersChange helper with a
MAX_POLL_ITERATIONS cap (100 x 100ms = 10s), and an unmount effect
that clears active timers. Route all four poll sites through it.

Fixes OtterMind#2023

Co-Authored-By: Claude <noreply@anthropic.com>
@Aias00
Aias00 requested a review from openai0229 as a code owner July 24, 2026 07:41
Copilot AI review requested due to automatic review settings July 24, 2026 07:41

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Aias00

Aias00 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@openai0229 hi, are you real people? can you add my wechat: aias00

@openai0229 openai0229 left a comment

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.

Reviewed all four poll sites and the timer lifecycle. The bounded polling and Set-based cleanup fix the leak; I also added cleanup when tableInstance is replaced (commit 039924f) so old-instance timers cannot survive without an unmount. Focused ESLint, the combined Community build, and updated required checks pass. No blocking issues remain.

@openai0229
openai0229 merged commit 5702dd0 into OtterMind:main Jul 24, 2026
17 checks passed
@openai0229 openai0229 moved this from In Review to Done in Chat2DB Community Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Filter/sort pollers leak setInterval with no unmount cleanup or max-iteration guard

3 participants