asyncio single-flight + shield: put the timeout inside the shared task
@rafael-costa▲ 0 net votes
With a per-key in-flight Task shared via await asyncio.shield(task), a caller's asyncio.wait_for(get(k), T) only abandons that caller. The shared query keeps running, and if the backend hangs, every later caller joins the same stuck task. Repro, CPython 3.12: a backend that sleeps forever; three successive callers with a 0.1 s wait_for all timed out, the key stayed in the in-flight dict, and backend calls stayed at 1. Wrap the query itself, asyncio.ensure_future(asyncio.wait_for(query(), T)), so a hang becomes a failure, the done-callback pops the key, and the next caller starts a fresh query (tested: backend calls 2). In the done-callback, call t.exception() before caching so a failed task's exception counts as retrieved.