[labs/ssr] fix patched directives memory leak#4515
Merged
AndrewJakubowicz merged 11 commits intomainfrom Jan 30, 2024
Merged
Conversation
Each time a patched directive is encountered, it gets patched again creating a subtle memory leak
🦋 Changeset detectedLatest commit: 7e4bd67 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
📊 Tachometer Benchmark ResultsSummarynop-update
render
update
update-reflect
Resultsthis-change
render
update
update-reflect
this-change, tip-of-tree, previous-release
render
update
nop-update
this-change, tip-of-tree, previous-release
render
update
this-change, tip-of-tree, previous-release
render
update
update-reflect
|
Contributor
|
The size of lit-html.js and lit-core.min.js are as expected. |
rictic
approved these changes
Jan 24, 2024
Collaborator
|
Nice! |
augustjk
approved these changes
Jan 24, 2024
Member
augustjk
left a comment
There was a problem hiding this comment.
Good find and fix!
I looked into whether it might be better to add the sentinel property in overrideDirectiveResolve but that lives in lit-html exported via private-ssr-support so it seems better to keep everything in this ssr package.
justinfagnani
requested changes
Jan 24, 2024
Note, this has to be done in a way that is backwards compatible. If lit-html is updated, and ssr is not updated, then overrideDirectiveResolve must continue to be accessible. Thus we add a new "public" private ssr api for patching _$resolve.
Contributor
Author
|
Great feedback which has been incorporated. Description has also been updated. Thank you! |
augustjk
reviewed
Jan 24, 2024
This reverts commit a1971f1.
This was referenced Jan 29, 2024
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
A memory leak was reported in Lit SSR.
Found by testing with #4514, and going test by test.
repeatdirective test contained this leak. After this PR the directive test no longer leaks.So far no other test shows memory leak characteristics.
Why?
Because we have a cache of
WeakMap<non patched directive, patched directive>. This is an issue because we can pull a patched directive off thevalue, and then it won't be found in the WeakMap. Because it's in the value of the WeakMap and not thekey. Thus the patched directive gets patched again and stored in the WeakMap. This repeats for the number of patch calls resulting in a nested doll of patched directive constructors.Fix
I implemented a super simple naive fix. Just flag the patched directive ctor with a sentinel property. Now when pulling the directive constructor off thevalue, we can immediately check if it's patched by looking at the sentinel.Fix was updated per Justin's feedback. It now patches the
_$resolvefield. This simplifies a lot of the book keeping code. Which has a much nicer memory footprint.However, this fix does need to be backwards compatible hence the new API,
patchDirectiveResolve. This allows for the following:overrideDirectiveResolve.patchDirectiveResolve, v3.1.2 (unreleased).Test plan
No memory test for this change because memory tests are expensive and slow. Instead this is covered by existing behavior tests. I can add tests if required.
The memory characteristics of this change were verified by pulling this change into #4514
Plan is to commit a memory test as a separate PR.