Commit a371461
fix: make
# Issue
On Python 3.13, the closed-queue signal is `asyncio.QueueShutDown`.
`event_consumer.py` aliased `asyncio.QueueShutDown` to `ClosedQueue`,
but `asyncio.QueueEmpty` can still arise on py3.13 and it's not handled
properly in `consume_all()`'s except blocks.
# How it's reproduced
In any `AgentExecutor` class:
```
# (...)
async def execute(
self,
request: RequestContext,
event_queue: EventQueue,
) -> None:
await event_queue.enqueue_event(
new_task(request.message)
)
```
In python < 3.13:
- Sending a `message/send` request works, a task is added to the
`InMemoryTaskStore`.
In python >= 3.13:
- Sending a `message/send` request crashes with exception:
```
File "venv/lib/python3.13/site-packages/a2a/server/apps/jsonrpc/jsonrpc_app.py", line 219, in _handle_requests
return await self._process_non_streaming_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
request_id, a2a_request, call_context
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "venv/lib/python3.13/site-packages/a2a/server/apps/jsonrpc/jsonrpc_app.py", line 306, in _process_non_streaming_request
handler_result = await self.handler.on_message_send(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
request_obj, context
^^^^^^^^^^^^^^^^^^^^
)
^
File "venv/lib/python3.13/site-packages/a2a/utils/telemetry.py", line 162, in async_wrapper
result = await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "venv/lib/python3.13/site-packages/a2a/server/request_handlers/jsonrpc_handler.py", line 87, in on_message_send
task_or_message = await self.request_handler.on_message_send(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
request.params, context
^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "venv/lib/python3.13/site-packages/a2a/utils/telemetry.py", line 162, in async_wrapper
result = await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "venv/lib/python3.13/site-packages/a2a/server/request_handlers/default_request_handler.py", line 282, in on_message_send
) = await result_aggregator.consume_and_break_on_interrupt(consumer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "venv/lib/python3.13/site-packages/a2a/server/tasks/result_aggregator.py", line 115, in consume_and_break_on_interrupt
async for event in event_stream:
...<20 lines>...
break
File "venv/lib/python3.13/site-packages/a2a/server/events/event_consumer.py", line 87, in consume_all
raise self._exception
File "venv/lib/python3.13/site-packages/a2a/server/events/event_consumer.py", line 94, in consume_all
event = await asyncio.wait_for(
^^^^^^^^^^^^^^^^^^^^^^^
self.queue.dequeue_event(), timeout=self._timeout
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/opt/homebrew/Cellar/[email protected]/3.13.5/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/tasks.py", line 507, in wait_for
return await fut
^^^^^^^^^
File "venv/lib/python3.13/site-packages/a2a/utils/telemetry.py", line 162, in async_wrapper
result = await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "venv/lib/python3.13/site-packages/a2a/server/events/event_queue.py", line 95, in dequeue_event
raise asyncio.QueueEmpty('Queue is closed.')
asyncio.queues.QueueEmpty: Queue is closed.
```
# Fix
## Code
- `event_consumer.consume_all`:
- Catch `(QueueClosed, asyncio.QueueEmpty)` and break only when
`queue.is_closed()` is True; otherwise continue polling.
- `event_queue.dequeue_event`:
- Version-guard the early-raise: on <3.13 keep raising `QueueEmpty` when
closed+empty; on ≥3.13 skip the early raise and rely on
`queue.shutdown()` to surface `QueueShutDown` exceptions.
## Tests
Added 2 tests which fail on current implementation, but pass after the
fix.
---------
Co-authored-by: taralesc <[email protected]>event_consumer tolerant to closed queues on py3.13 (#407)1 parent da14cea commit a371461
File tree
4 files changed
+69
-8
lines changed- src/a2a/server/events
- tests/server/events
4 files changed
+69
-8
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
138 | | - | |
| 138 | + | |
139 | 139 | | |
140 | 140 | | |
141 | 141 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
93 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
94 | 99 | | |
95 | 100 | | |
96 | 101 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
324 | 324 | | |
325 | 325 | | |
326 | 326 | | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
327 | 380 | | |
328 | 381 | | |
329 | 382 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
169 | 169 | | |
170 | 170 | | |
171 | 171 | | |
172 | | - | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
173 | 175 | | |
174 | 176 | | |
175 | 177 | | |
| |||
178 | 180 | | |
179 | 181 | | |
180 | 182 | | |
181 | | - | |
| 183 | + | |
182 | 184 | | |
183 | 185 | | |
184 | 186 | | |
| |||
192 | 194 | | |
193 | 195 | | |
194 | 196 | | |
195 | | - | |
| 197 | + | |
196 | 198 | | |
197 | 199 | | |
198 | 200 | | |
| |||
214 | 216 | | |
215 | 217 | | |
216 | 218 | | |
217 | | - | |
| 219 | + | |
218 | 220 | | |
219 | 221 | | |
220 | 222 | | |
| |||
230 | 232 | | |
231 | 233 | | |
232 | 234 | | |
233 | | - | |
| 235 | + | |
| 236 | + | |
234 | 237 | | |
235 | 238 | | |
236 | 239 | | |
| |||
240 | 243 | | |
241 | 244 | | |
242 | 245 | | |
243 | | - | |
| 246 | + | |
244 | 247 | | |
245 | 248 | | |
246 | 249 | | |
| |||
0 commit comments