Commit 15ad5ab
committed
fix: release asyncio.Lock before streaming to prevent orphan on client disconnect
Narrow the lock scope in ContextWebSocket.execute() so that the lock
is only held during the prepare+send phase, not during result streaming.
Previously, the lock was held for the entire generator lifetime including
the _wait_for_result() streaming loop. When a client disconnected
(e.g. SDK timeout), Starlette abandoned the generator while it was
blocked at `await queue.get()`. The lock stayed held until the kernel
finished internally, blocking all subsequent executions on the same
context and causing cascading timeouts.
The fix moves the streaming phase (Phase B) outside the `async with
self._lock` block. This is safe because results are routed by unique
message_id in _process_message() — no shared state is accessed during
streaming. A try/finally ensures the execution entry is cleaned up
even if the generator is abandoned.
Fixes #2131 parent 6d703a4 commit 15ad5ab
1 file changed
Lines changed: 15 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
294 | 294 | | |
295 | 295 | | |
296 | 296 | | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
297 | 305 | | |
298 | 306 | | |
299 | 307 | | |
| |||
327 | 335 | | |
328 | 336 | | |
329 | 337 | | |
330 | | - | |
331 | 338 | | |
332 | 339 | | |
333 | 340 | | |
| |||
362 | 369 | | |
363 | 370 | | |
364 | 371 | | |
365 | | - | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
366 | 376 | | |
367 | 377 | | |
368 | | - | |
369 | | - | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
370 | 381 | | |
371 | 382 | | |
372 | 383 | | |
| |||
0 commit comments