Skip to content

[data grid] Stop the data source polling after the grid unmounts - #23709

Merged
LukasTy merged 5 commits into
mui:masterfrom
LukasTy:claude/data-source-polling-after-unmount
Sep 30, 2026
Merged

LukasTy merged 5 commits into
mui:masterfrom
LukasTy:claude/data-source-polling-after-unmount

Conversation

@LukasTy

@LukasTy LukasTy commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

With dataSourceRevalidateMs set, each response calls startPolling(). A request that settles after the grid unmounts restarts the polling. No cleanup clears the new interval, so the unmounted grid keeps calling getRows() until the page reloads.

Changes in useGridDataSourceBase, useGridDataSourceLazyLoader and useGridDataSourceNestedLazyLoader:

  • startPolling() does nothing after the unmount and while an <Activity> is hidden.
  • Polling resumes when a hidden <Activity> becomes visible again. Before, it did not resume.
  • The lazy loaders drop a queued revalidation fetch on a real unmount. A hidden <Activity> keeps the root connected, so its queued fetch still runs.
  • Removes the setProps({ dataSourceRevalidateMs: 0 }) workaround from [test] Fix flaky Data Grid Pro data source tree data tests #22659. It worked around the same leak in the tree data tests only.

This leak also causes CI flakes. The browser tests run with isolate: false, so a leaked 1ms poller stays alive in the later test files of the same page. There, each vi.runAllTimersAsync() spins until it throws Aborting after running 10000 timers, assuming an infinite loop!. In the last 14 days:

  • 32 test_browser and test_browser_react_18 jobs failed in sorting.DataGridPro (for example this job on master).
  • 8 jobs hit the CircleCI "Too long with no output (exceeded 10m0s)" limit. In all of them, columnHeaders.DataGridPro.test.tsx (about 20 runAllTimersAsync() calls) never finished (for example this job on master).

The tests cover the unmount case for all three hooks, the Activity pause and resume, and the queued fetch while an <Activity> is hidden. Each test fails when its part of the fix is removed. With all x-data-grid-pro test files in one page, no interval stays alive after any file.

Generated with Claude Code

A request that settles after the grid unmounts calls `startPolling()`.
No cleanup clears the new interval, so the unmounted grid keeps calling
`getRows()`. `startPolling()` now does nothing after the unmount.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LukasTy LukasTy added type: bug It doesn't behave as expected. scope: data grid Changes related to the data grid. feature: Server integration Better integration with backends, e.g. data source labels Sep 29, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-23709--material-ui-x.netlify.app/
QR code for https://deploy-preview-23709--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 🔺+83B(+0.02%) 🔺+23B(+0.02%)
@mui/x-data-grid-pro 🔺+467B(+0.08%) 🔺+135B(+0.08%)
@mui/x-data-grid-premium 🔺+468B(+0.06%) 🔺+121B(+0.06%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-scheduler 0B(0.00%) 0B(0.00%)
@mui/x-scheduler-premium 0B(0.00%) 0B(0.00%)
@mui/x-chat 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@LukasTy LukasTy self-assigned this Sep 29, 2026
@LukasTy
LukasTy requested a balanced review from Copilot September 29, 2026 13:30

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

Copilot review overview

🟡 Changes recommended

The two lazy-loader guards lack direct regression coverage for requests settling after unmount.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Prevents data-source polling from restarting after grid unmount.

Changes:

  • Adds unmount-aware polling guards across data-source implementations.
  • Adds a regression test and removes test workarounds.
File Description
packages/​x-data-grid/​src/​tests/​dataSource.DataGrid.test.tsx Tests polling after unmount.
packages/​x-data-grid/​src/​hooks/​features/​dataSource/​useGridDataSourceBase.ts Guards standard polling.
packages/​x-data-grid-pro/​src/​tests/​dataSourceTreeData.DataGridPro.test.tsx Removes polling workarounds.
packages/​x-data-grid-pro/​src/​hooks/​features/​serverSideLazyLoader/​useGridDataSourceNestedLazyLoader.ts Guards nested lazy polling.
packages/​x-data-grid-pro/​src/​hooks/​features/​serverSideLazyLoader/​useGridDataSourceLazyLoader.ts Guards flat lazy polling.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

LukasTy and others added 3 commits September 29, 2026 16:40
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A revalidation that `debouncedFetchRows` queued still sent `getRows()`
after the grid unmounted. Clear it on a real unmount. A hidden
`<Activity>` keeps the root connected, so its queued fetch still runs.

The tests now restore real timers in the test body, because
`onTestFinished` runs after the global `afterEach`. A new test covers
the queued fetch while an `<Activity>` is hidden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

Copilot review overview

🟢 Approval recommended

The lifecycle guards address the leak consistently across all polling implementations with focused regression coverage.

Review effort: Balanced
Findings: None

Resolved since last review (2)

@michelengelen michelengelen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM... the only suggestion from my side would be to extract the repetitive useEffect into a custom hook that can be imported

@LukasTy

LukasTy commented Sep 30, 2026

Copy link
Copy Markdown
Member Author

LGTM... the only suggestion from my side would be to extract the repetitive useEffect into a custom hook that can be imported

I'll look at addressing this separately.

@LukasTy
LukasTy merged commit 360d9f3 into mui:master Sep 30, 2026
24 checks passed
@LukasTy
LukasTy deleted the claude/data-source-polling-after-unmount branch September 30, 2026 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: Server integration Better integration with backends, e.g. data source scope: data grid Changes related to the data grid. test type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants