fix(pipecat): retain strong references to background storage tasks to prevent GC#1008
Open
devteamaegis wants to merge 1 commit into
Open
fix(pipecat): retain strong references to background storage tasks to prevent GC#1008devteamaegis wants to merge 1 commit into
devteamaegis wants to merge 1 commit into
Conversation
…nt GC asyncio.create_task() is only weakly referenced by the event loop. If the caller discards the returned Task object the GC can destroy it before the coroutine finishes, silently dropping any messages that were queued for storage. The Cartesia SDK in this same repo already uses the correct pattern (_background_tasks set + add_done_callback(discard)). Apply the same fix to SupermemoryPipecatService: * Add `_background_tasks: set` in __init__ * Save every storage task in the set; remove it via done-callback once complete * Clear the set in reset_memory_tracking() Adds tests/test_background_task_tracking.py with five test cases: - presence of _background_tasks attribute - task is held in the set while running - task is removed from the set after completion - a forced GC cycle cannot collect a tracked task mid-execution - reset_memory_tracking clears the set
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.
Problem
In
SupermemoryPipecatService.process_frame, conversation messages are storedvia a fire-and-forget coroutine:
The
Taskobject returned byasyncio.create_taskis immediately discarded.Python's
asyncioevent loop only holds weak references to scheduledtasks, so the garbage collector is free to destroy a task at any time — even
while it is still awaiting an I/O call inside
_store_messages. On a GCcycle this can silently kill an in-flight
supermemory.memories.add()request,dropping messages with no error logged.
The
SupermemoryCartesiaAgentin the same repo (cartesia-sdk-python) alreadyuses the correct pattern: it saves each task in a
_background_tasksset andremoves it via
add_done_callback(discard)once the coroutine finishes.Fix
Apply the same pattern to
SupermemoryPipecatService:self._background_tasks: set = set()in__init__.add_done_callback.reset_memory_tracking().Tests
tests/test_background_task_tracking.py(all 5 pass):test_background_tasks_set_exists– attribute present after inittest_task_held_during_execution– task is in the set while running, removed aftertest_task_removed_after_completion– set is empty once coroutine finishestest_gc_cannot_collect_tracked_task– forcedgc.collect()mid-execution can't kill a tracked tasktest_reset_clears_background_tasks–reset_memory_tracking()empties the set