fix(server): cancel and await producer task before cleanup to prevent GC warning (Fixes #1121)#1125
Open
isheng-eqi wants to merge 2 commits into
Open
Conversation
… GC warning (Fixes a2aproject#1121) On the normal-completion teardown path, _run_consumer's finally block was releasing the ActiveTask reference (via _maybe_cleanup) before the producer task had finished, leaving it parked on _request_queue.get(). When GC reclaimed the ActiveTask, the still-pending producer was destroyed, triggering asyncio 'Task was destroyed but it is pending!' warnings. Fix: cancel _producer_task and await it (suppressing CancelledError) before calling _maybe_cleanup(), mirroring what cancel() already does on the explicit cancel path. This ensures deterministic teardown and prevents the GC warning.
Contributor
There was a problem hiding this comment.
Code Review
This pull request ensures that the producer task is cancelled and awaited before cleanup when the consumer finishes first, preventing asyncio "Task was destroyed but it is pending!" warnings. A regression test has been added to verify this behavior. I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
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.
Summary
Fix an asyncio "Task was destroyed but it is pending!" warning in
ActiveTaskthat fires under continuous load when the consumer finishes before the producer on the normal-completion teardown path.Problem
ActiveTaskhas two teardown paths with asymmetric producer cleanup:cancel()): cancels_producer_task, agent cancels, waits for_is_finished→ clean teardown_run_consumerfinally): sets_is_finished, calls_maybe_cleanup()→_on_cleanup(self)→ releases ActiveTask reference without cancelling or awaiting the producerWhen the consumer finishes first and the reference is dropped, the still-pending producer is GC'd while parked on
_request_queue.get()(or inside its finally block at line 566), triggering:Observed 103× over a multi-hour run under continuous load per #1121.
Fix
In
_run_consumer's finally block, cancel and await the producer task before_maybe_cleanup(), mirroring whatcancel()already does:This ensures the producer's finally block (which closes event queues) completes deterministically before the ActiveTask reference is released.
Test Plan
test_producer_cancelled_on_normal_completion: simulates consumer finishing while producer is pending, verifies producer is cancelled + awaited + cleanup callback firesruff check+ruff format+ty checkpassCloses #1121