Commit 4a62434
committed
fix: configure uvicorn properly for 3.14 and Windows instead of abandoning shutdown
Two root-cause fixes, no warning suppression:
Python 3.14:
uvicorn's interface='auto' autodetect calls asyncio.iscoroutinefunction
on the app's __call__ to distinguish ASGI2 from ASGI3. That function is
deprecated on 3.14, and pyproject.toml's filterwarnings=error promotes
the warning to an exception in the server thread — which dies silently
while our pre-bound socket keeps accepting connections into the kernel
queue, turning a loud startup crash into a 5-minute ReadTimeout.
Starlette apps are ASGI3. Setting interface='asgi3' skips the autodetect
entirely — we're just telling uvicorn something we already know.
Windows Proactor:
force_exit=True short-circuits _wait_tasks_to_complete's connection-drain
loops immediately. connection.shutdown() was called, but we never waited
for the transports to actually close; they still have pending Overlapped
Recv operations when the event loop is torn down, and GC later finds
them during an unrelated test.
timeout_graceful_shutdown=1 gives uvicorn a bounded window to drain
connections naturally, then on timeout calls t.cancel() on remaining
tasks — proper asyncio cancellation that unwinds the transports through
their CancelledError paths instead of abandoning them mid-I/O. Tests
that close their httpx clients cleanly (all of them, in practice) never
hit the timeout; the drain loop finds connections already empty.1 parent 21a3979 commit 4a62434
1 file changed
+12
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
68 | 80 | | |
69 | 81 | | |
70 | 82 | | |
| |||
81 | 93 | | |
82 | 94 | | |
83 | 95 | | |
84 | | - | |
85 | 96 | | |
86 | 97 | | |
0 commit comments