Skip to content

Conversation

@meoow113
Copy link
Contributor

@meoow113 meoow113 commented Aug 4, 2025

Fixes #367

  • Add clear_events method for immediate queue cleanup
  • Integrate with event_consumer to prevent hanging
  • Support child queue clearing for complete cleanup

@meoow113 meoow113 requested a review from a team as a code owner August 4, 2025 09:05
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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 @meoow113, 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 implements a crucial bug fix related to client hanging issues in the event processing pipeline. The solution involves enhancing the EventQueue and EventConsumer components to ensure that all pending events are explicitly cleared before an event queue is closed. This prevents potential deadlocks or resource contention that could lead to the client becoming unresponsive, particularly in scenarios involving complex agent execution flows.

Highlights

  • Bug Fix: Client Hanging Issue: This pull request directly addresses a bug where the client would hang, particularly when using AgentExecutor and encountering a double await in an execute method. The core of the fix lies in ensuring proper cleanup of event queues.
  • New Event Queue Management Method: Introduced a new asynchronous method, clear_events, within the EventQueue class. This method is designed to efficiently remove all pending events from the current queue and, optionally, from any associated child queues, preventing unprocessed events from causing issues.
  • Enhanced Event Consumer Cleanup: Modified the EventConsumer to utilize the newly added clear_events method. Specifically, when a final event is detected and the consumer is preparing to close its queue, it now explicitly clears any remaining events, ensuring a clean shutdown and resolving the hanging behavior.
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 or fill out our survey to provide feedback.

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

  1. 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.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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 introduces a clear_events method to the EventQueue to address a client hanging issue. The clear_events method clears pending events before closing the queue, preventing deadlocks. A potential concurrency issue was identified where the lock is held for an extended period while clearing child queues. A suggestion has been provided to refactor this for improved performance and safety by releasing the lock before awaiting the child tasks.

@holtskinner holtskinner changed the title FIX [Bug]#367: Client hangs when implementing AgentExecutor and awai… fix: Client hangs when implementing AgentExecutor and awaiting twice in execute method Aug 4, 2025
Copy link
Member

@holtskinner holtskinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add more in your PR description for what this does?

@meoow113
Copy link
Contributor Author

meoow113 commented Aug 5, 2025

Can you please add more in your PR description for what this does?

ok, i have updated my PR description

严骏驰 added 3 commits August 6, 2025 10:17
… forced queue shutdown

- Add immediate parameter to EventQueue.close() method to allow immediate
  queue closure by discarding all pending events
- Update EventConsumer.consume_all() to use close(immediate=True) when
  encountering the first final event to prevent blocking on subsequent
  final events
- This resolves the issue where multiple final events in queue would
  cause the consumer to block after processing the first final event

The immediate parameter provides a way to force close the queue without
waiting for all events to be processed, which is useful in scenarios
where the consumer needs to exit immediately upon encountering a final
event, regardless of remaining events in the queue.
Updated and improved code comments/docstrings.
Updated the format
@meoow113 meoow113 requested a review from holtskinner August 6, 2025 09:31
@meoow113
Copy link
Contributor Author

meoow113 commented Aug 6, 2025

I have explained this in other replay

@meoow113 meoow113 closed this Aug 6, 2025
@meoow113 meoow113 deleted the fix-bug#367-client_hangs branch August 6, 2025 09:55
@meoow113 meoow113 restored the fix-bug#367-client_hangs branch August 6, 2025 09:55
@meoow113 meoow113 reopened this Aug 6, 2025
@meoow113
Copy link
Contributor Author

meoow113 commented Aug 6, 2025

Can you please add more in your PR description for what this does?

I have explained this in other replay

@meoow113 meoow113 marked this pull request as draft August 7, 2025 11:11
@meoow113 meoow113 marked this pull request as ready for review August 8, 2025 07:32
@pstephengoogle
Copy link
Contributor

Overall, this looks good. Can we add unit tests to exercise the new patterns/behaviors?

holtskinner and others added 13 commits August 12, 2025 21:14
…r and clear_events method

- Add tests for close(immediate=True) behavior and child queue propagation
- Add tests for clear_events() with various scenarios (empty, closed, with children)
- Add tests for concurrent execution and exception handling in clear_events
- Remove redundant test_close_with_immediate_false as existing tests already cover this path
- Fix linter errors in Python version-specific test mocks

Ensures proper test coverage for the new queue shutdown and cleanup functionality.
… loop

- Replace per-iteration try/except with a single try/except around a while True loop
- Exit on asyncio.QueueEmpty to stop draining when the queue is empty
- Reduces exception overhead and satisfies Ruff PERF203 without changing behavior
…ility

- Move try/except outside the loop to eliminate per-iteration exception overhead (fixes Ruff PERF203)
- Keep lock scope minimal: drain parent queue under lock, release before awaiting children
- Use asyncio.gather for concurrent child queue clearing with safe exception handling
- Handle Python 3.13 asyncio.QueueShutDown in clear_events via a version-safe except clause
  (fallback to QueueEmpty on <=3.12)

No public API changes; behavior is preserved on older Python versions.
…y compatibility

- Replace getattr-based exception handling with explicit version check
- Use type(e).__name__ comparison to identify QueueShutDown in Python 3.13+
- Re-raise unexpected exceptions to maintain proper error propagation
- Fixes mypy error: Exception type must be derived from BaseException
@holtskinner holtskinner merged commit c147a83 into a2aproject:main Aug 20, 2025
5 checks passed
holtskinner pushed a commit that referenced this pull request Aug 20, 2025
🤖 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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Client hangs when implementing AgentExecutor and awaiting twice in execute method

3 participants