ReadThroughCache of size 0 provides the guarantee that as long as a ValueHandle returned by ReadThroughCache::acquireAsync is kept in scope, subsequent calls to acquireAsync will keep returning it and won't result in a lookup. However, as soon as that ValueHandle leaves scope, the subsequent invocation of acquireAsync should look it up again.
This guarantee is broken a bit, which is demonstrated by a single-threaded unit-test. Even though the ValueHandle from the current iteration goes out of scope and is destroyed at the end of this loop, since this value comes from the setting of a SharedSemiFuture, it is possible that there is still leftover reference on the ValueHandle somewhere throughout the SharedSemiFuture infrastructure, which would keep it alive.
This is not necessarily terrible from the point of view of the contract of ReadThroughCache of size zero, but makes it difficult to write tests, so we should fix it.