-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[BUG]: Delete collection resource leak (single-node Chroma) #3297
base: main
Are you sure you want to change the base?
Conversation
Reviewer ChecklistPlease leverage this checklist to ensure your code review is thorough before approving Testing, Bugs, Errors, Logs, Documentation
System Compatibility
Quality
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
2e113a0
to
b53dadb
Compare
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.
Thanks for identifying the leak and raising the fix. I did not see this earlier so did not review earlier. my miss. Reviewed it now.
@@ -384,10 +384,11 @@ def delete_collection( | |||
) | |||
|
|||
if existing: | |||
segments = self._sysdb.get_segments(collection=existing[0].id) |
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.
I feel we should try not to call sysdb for getting segments. It adds extra call to the backend for distributed chroma.
Seeing the current code, I see we are already calling sysdb.get_segments() from the manager, so you are simply moving that line here, and not adding extra calls. But i feel we can do better.
Do you think we should just call delete_segment() from delete_collection() ?
So we can add this snippet back -
for s in self._manager.delete_segments(existing[0]["id"]):
self._sysdb.delete_segment(s)
and do a no-op inside delete_segments() in db/impl/grpc/client.py
Will that fix the leak ?
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.
using this snippet:
for s in self._manager.delete_segments(existing[0]["id"]):
self._sysdb.delete_segment(s)
Makes sense however we revert back to a non-atomic deletion of sysdb resources. In the above snippet we'd delete the segments separately from deleting the collection, which I wanted to avoid on purpose which is why I pulled the get of the segments here before the were atomically deleted as part of self._sysdb.delete_collection
.
Why do you think that this would cause extra calls in the distributed backend?
@@ -76,8 +76,7 @@ def prepare_segments_for_new_collection( | |||
return [vector_segment, record_segment, metadata_segment] | |||
|
|||
@override | |||
def delete_segments(self, collection_id: UUID) -> Sequence[UUID]: | |||
segments = self._sysdb.get_segments(collection=collection_id) |
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.
@rohitcpbot, is this your concern about the call to distributed sysdb?
b53dadb
to
ba07228
Compare
Description of changes
Closes #3296
The delete collection logic slightly changes to accomodate the fix without breaking the transactional integrity of
self._sysdb.delete_collection
. Thechromadb.segment.SegmentManager.delete_segments
had to change to accept the list of segments to delete instead ofcollection_id
.Summarize the changes made by this PR.
Test plan
How are these changes tested?
pytest
for python,yarn test
for js,cargo test
for rustDocumentation Changes
N/A