-
Notifications
You must be signed in to change notification settings - Fork 240
fix: make event_consumer
tolerant to closed queues on py3.13
#407
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: make event_consumer
tolerant to closed queues on py3.13
#407
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.
Summary of Changes
Hello @ovidiutaralesca, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request resolves a critical issue where the event consumer would crash on Python 3.13 due to changes in how asyncio
queues signal closure. The fix involves updating the event_consumer
to correctly handle asyncio.QueueEmpty
exceptions when the queue is truly closed, and adjusting the event_queue
to align its dequeue_event
behavior with Python 3.13's asyncio.QueueShutDown
signal. These changes ensure the event processing remains stable and reliable across different Python versions, preventing unexpected crashes during event consumption.
Highlights
- Python 3.13 Compatibility: The core issue addressed is a crash in the
event_consumer
on Python 3.13, caused byasyncio.QueueEmpty
being raised when the queue is closed, which was not previously handled. - Robust Exception Handling: The
consume_all
method inevent_consumer.py
now explicitly catchesasyncio.QueueEmpty
alongsideQueueClosed
, ensuring that the consumer correctly identifies a truly closed queue before breaking the event consumption loop. - Version-Specific Queue Behavior: A version check (
sys.version_info < (3, 13)
) was added toevent_queue.dequeue_event
to differentiate behavior for Python 3.13+, preventing an earlyQueueEmpty
raise and allowingasyncio.QueueShutDown
to signal queue closure as intended by the newer Python version. - Enhanced Test Coverage: Two new asynchronous tests were added to
test_event_consumer.py
to validate the fix, covering scenarios whereasyncio.QueueEmpty
is raised on both closed and open queues, ensuring the consumer behaves as expected.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
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.
Code Review
This pull request addresses a compatibility issue with Python 3.13's asyncio.Queue
behavior. The changes are well-implemented and correctly handle the different exception types for closed queues across Python versions. The modification in event_consumer.py
to catch both QueueClosed
and asyncio.QueueEmpty
is a robust fix, and the version-specific logic in event_queue.py
is appropriate. The newly added tests are comprehensive and validate the fix effectively, covering scenarios for both temporarily empty and permanently closed queues. Overall, this is a solid contribution that improves compatibility and reliability.
5eb03ff
to
dbc4a12
Compare
Thanks for this fix! |
Head branch was pushed to by a user without write access
7a95324
to
7b6d0a2
Compare
@mikeas1 thank you for the review! I had to make a small adjustment to an existing test to work on py3.13. |
event_consumer
tolerant to closed queues on py3.13
🤖 I have created a release *beep* *boop* --- ## [0.3.2](v0.3.1...v0.3.2) (2025-08-20) ### Bug Fixes * Add missing mime_type and name in proto conversion utils ([#408](#408)) ([72b2ee7](72b2ee7)) * Add name field to FilePart protobuf message ([#403](#403)) ([1dbe33d](1dbe33d)) * Client hangs when implementing `AgentExecutor` and `await`ing twice in execute method ([#379](#379)) ([c147a83](c147a83)) * **grpc:** Update `CreateTaskPushNotificationConfig` endpoint to `/v1/{parent=tasks/*/pushNotificationConfigs}` ([#415](#415)) ([73dddc3](73dddc3)) * make `event_consumer` tolerant to closed queues on py3.13 ([#407](#407)) ([a371461](a371461)) * non-blocking `send_message` server handler not invoke push notification ([#394](#394)) ([db82a65](db82a65)) * **proto:** Add `icon_url` to `a2a.proto` ([#416](#416)) ([00703e3](00703e3)) * **spec:** Suggest Unique Identifier fields to be UUID ([#405](#405)) ([da14cea](da14cea)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Issue
On Python 3.13, the closed-queue signal is
asyncio.QueueShutDown
.event_consumer.py
aliasedasyncio.QueueShutDown
toClosedQueue
, butasyncio.QueueEmpty
can still arise on py3.13 and it's not handled properly inconsume_all()
's except blocks.How it's reproduced
In any
AgentExecutor
class:In python < 3.13:
message/send
request works, a task is added to theInMemoryTaskStore
.In python >= 3.13:
message/send
request crashes with exception:Fix
Code
event_consumer.consume_all
:(QueueClosed, asyncio.QueueEmpty)
and break only whenqueue.is_closed()
is True; otherwise continue polling.event_queue.dequeue_event
:QueueEmpty
when closed+empty; on ≥3.13 skip the early raise and rely onqueue.shutdown()
to surfaceQueueShutDown
exceptions.Tests
Added 2 tests which fail on current implementation, but pass after the fix.