-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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(NODE-5691): make findOne() close implicit session to avoid memory leak #3889
Conversation
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.
Hey @vkarpov15, thanks, I threw in a simple test to prevent regression, thanks for the help.
Just sharing some context: I investigated this issue it turns out it is specifically when the collection is timeseries in a 7.0+ server because of how it returns the cursor document. Nonetheless, we do want the driver to clean up the cursor resource and not rely on a server result to hit our cleanup logic.
return this.find(filter, options).limit(-1).batchSize(1).next(); | ||
const cursor = this.find(filter, options).limit(-1).batchSize(1); | ||
const res = await cursor.next(); | ||
await cursor.close(); |
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.
Calling close without try/finally here I believe is correct, a cursor that receives an error always calls close. Also, calling close unconditionally makes sense because close already includes the logic to no-op when the cursor has already been closed.
Description
I found this potential issue while troubleshooting Automattic/mongoose#13829. Running the following Mongoose script:
Using --max-heap-size to constrain memory, without this PR, leads to OOM:
With this PR:
It looks like the issue is that, while
toArray()
andasyncIterator
callclose()
,findOne()
does not. And that meansfindOne()
's implicitly created session never ends, leading to what looks like a memory leak.What is changing?
Explicitly
close()
cursor infindOne()
in order to ensure that the driver callsendSession()
on the implicitly created session.Is there new documentation needed for these changes?
No
What is the motivation for this change?
See description
Release Highlight
Fixed leak in
findOne()
under specific conditionsWhen running a findOne against a time series collection due to the way the server returns the resulting cursor information the driver left the implicit session for the cursor un-ended. Now the cursor will always be cleaned up regardless of the outcome of the find operation.
Double check the following
npm run check:lint
scripttype(NODE-xxxx)[!]: description
feat(NODE-1234)!: rewriting everything in coffeescript