Skip to content

fix: premature cleanup in strict mode and improved performance#429

Closed
welkinwong wants to merge 2 commits intometeor:masterfrom
welkinwong:master
Closed

fix: premature cleanup in strict mode and improved performance#429
welkinwong wants to merge 2 commits intometeor:masterfrom
welkinwong:master

Conversation

@welkinwong
Copy link
Contributor

When strict mode is enabled (development mode only), useEffect may run 1 to 2 times. Due to the outer layer throwing a promise, the multiple executions of useEffect in this scenario can lead to premature cleanup of subscriptions and cachedSubscription (i.e., before the component unmounts). Therefore, it is necessary to check the timeout to ensure that subscriptions and cachedSubscription are only cleared after the component has unmounted.

@welkinwong
Copy link
Contributor Author

Supplementary Description: Premature cleanup of subscriptions and cachedSubscription can lead to infinite re-mounting of components in strict mode (especially when used in conjunction with useFind, causing repeated execution of useSubscribe). This occurs because prematurely clearing cachedSubscription results in re-throwing a Promise, which suspends the component and creates a loop.

@StorytellerCZ
Copy link
Collaborator

This would explain some of the issues I ran into! Looking forward to a patch release with this!

@StorytellerCZ
Copy link
Collaborator

Also very much appreciate the lodash removal.

@nachocodoner
Copy link
Member

nachocodoner commented Apr 3, 2025

I understand the problem you describe and the code makes sense. But, is there any chance to provide tests capturing the problem you describe?

I’m hesitant to merge changes in these critical packages without reliable evidence that we fully understand the issue and the fix. Since we’ve just restored tests in this repository, it’s a good opportunity to ensure they’re up to date and accurately cover the problem.

In strict mode (development only), useEffect may run 1-2 times. Throwing a promise outside can cause premature cleanup of subscriptions and cachedSubscription before unmount. To avoid this, check the timeout to ensure cleanup only occurs after unmount.
@welkinwong
Copy link
Contributor Author

I understand the problem you describe and the code makes sense. But, is there any chance to provide tests capturing the problem you describe?

I’m hesitant to merge changes in these critical packages without reliable evidence that we fully understand the issue and the fix. Since we’ve just restored tests in this repository, it’s a good opportunity to ensure they’re up to date and accurately cover the problem.

@nachocodoner Your argument is perfectly valid, so I've added two test cases to cover these changes. :)

@welkinwong
Copy link
Contributor Author

This test fails on the legacy code but passes in the current PR.

Snipaste_2025-04-04_17-31-17

@nachocodoner
Copy link
Member

I didn't realize that the changes here are also included, #430

Closing then in favor of #435

@nachocodoner
Copy link
Member

This change is available in meteor add react-meteor-data@3.0.5-beta.0. Please, verify it works as expected.

@welkinwong
Copy link
Contributor Author

This change is available in meteor add react-meteor-data@3.0.5-beta.0. Please, verify it works as expected.

Verified - normal operation 👏

italojs pushed a commit that referenced this pull request Jun 11, 2025
… server side and improved performance

1. On the server, useEffect doesn't run, so cached find data isn't cleared. Even after database updates, stale data is returned on subsequent requests.
2. useFindSuspense can't run on the client (non-reactive data makes it pointless), so the useEffect part was removed.
3. lodash.remove is no longer in use and can be removed.
4. According to 7d45b72, the package-lock.json file can be deleted.

This PR depends on #429
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants