-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix map memory leak #3444
Fix map memory leak #3444
Conversation
@brunorzn: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Meteor Contributor Agreement here: https://contribute.meteor.com/ |
…defined. As demonstrated in the Danger test[0] on #3444, the `author` property is not always set. While it could make sense to individually look at each individual commit's "login", Git commits are not always tied to GitHub users so it seems more relevant to look at the GitHub login of the user (or bot!) opening the PR, when making decisions about whether to apply bot-only policies. [0]: https://circleci.com/gh/apollographql/apollo-client/8427
…ub user. (#3502) From my commit message on 5d3889c: --- As demonstrated in the Danger test[0] on #3444, the `author` property is not always set. While it could make sense to individually look at each individual commit's "login", Git commits are not always tied to GitHub users so it seems more relevant to look at the GitHub login of the user (or bot!) opening the PR, when making decisions about whether to apply bot-only policies. [0]: https://circleci.com/gh/apollographql/apollo-client/8427
... also, removed all cache-related features when this dependencies were needed.
Hi @brunorzn - it looks like the tests need to be adjusted a bit, to accommodate for the cache removal. If you don't mind adjusting the tests, I'll do a final review when everything is passing. Thanks! |
@hwillson : sorry about those failing tests. I did it too quickly during a meeting. I just felt like removing this couple of "should memoize and return cached results" tests. Also, strangely, I had to modify the end of this test file, by adding an extra }), see commit 4557ca7 : what do you think ? The tests should now pass. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome @brunorzn - this all looks great! Thanks very much! I've updated the CHANGELOG
, and will merge once the tests have completed. Thanks again!
@@ -982,4 +952,5 @@ describe('getDirectivesFromDocument', () => { | |||
const doc = getDirectivesFromDocument([{ name: 'client' }], query, true); | |||
expect(print(doc)).toBe(print(expected)); | |||
}); | |||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, looks like the describe
on line 917 wasn't closed - good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I had to like triple check this to be sure it wasn't me ;) (basically, eslint caught it, not me)
Thanks @hwillson ! Hopefully this will be merged soon ! |
This change will cause some problems for #3394, since I have been relying on the reuse of query document objects across repeated cache reads, and this change causes the document to be different every time. I think a better way to fix the memory leak would be to use a |
After #3444 removed `Map`-based caching for `addTypenameToDocument` (in order to fix memory leaks), the `InMemoryCache#transformDocument` method now creates a completely new `DocumentNode` every time it's called (assuming this.addTypename is true, which it is by default). This commit uses a `WeakMap` to cache calls to `addTypenameToDocument` in `InMemoryCache#transformDocument`, so that repeated cache reads will no longer create an unbounded number of new `DocumentNode` objects. The benefit of the `WeakMap` is that it does not prevent its keys (the original `DocumentNode` objects) from being garbage collected, which is another way of preventing memory leaks. Note that `WeakMap` may have to be polyfilled in older browsers, but there are many options for that. This optimization will be important for #3394, since the query document is involved in cache keys used to store cache partial query results. cc @hwillson @jbaxleyiii @brunorzn
After #3444 removed `Map`-based caching for `addTypenameToDocument` (in order to fix memory leaks), the `InMemoryCache#transformDocument` method now creates a completely new `DocumentNode` every time it's called (assuming this.addTypename is true, which it is by default). This commit uses a `WeakMap` to cache calls to `addTypenameToDocument` in `InMemoryCache#transformDocument`, so that repeated cache reads will no longer create an unbounded number of new `DocumentNode` objects. The benefit of the `WeakMap` is that it does not prevent its keys (the original `DocumentNode` objects) from being garbage collected, which is another way of preventing memory leaks. Note that `WeakMap` may have to be polyfilled in older browsers, but there are many options for that. This optimization will be important for #3394, since the query document is involved in cache keys used to store cache partial query results. cc @hwillson @jbaxleyiii @brunorzn
After #3444 removed `Map`-based caching for `addTypenameToDocument` (in order to fix memory leaks), the `InMemoryCache#transformDocument` method now creates a completely new `DocumentNode` every time it's called (assuming `this.addTypename` is true, which it is by default). This commit uses a `WeakMap` to cache calls to `addTypenameToDocument` in `InMemoryCache#transformDocument`, so that repeated cache reads will no longer create an unbounded number of new `DocumentNode` objects. The benefit of the `WeakMap` is that it does not prevent its keys (the original `DocumentNode` objects) from being garbage collected, which is another way of preventing memory leaks. Note that `WeakMap` may have to be polyfilled in older browsers, but there are many options for that. This optimization will be important for #3394, since the query document is involved in cache keys used to store cache partial query results. cc @hwillson @jbaxleyiii @brunorzn
This helps avoid the related memory leak issue identified in #3444.
using object as keys in map can cause memory leaks since if the reference to the same-value object is different, it will not find it.
This is the case, for example, when you use InMemoryCache during SSR.
Example of code that reproduces the leak :
also, see issue apollographql/apollo-link-state#248
Checklist: