This mocks a generic container that wraps a cache.
There are two structs that wrap containers -- a Container
and a
PurgeCache
.
Container
can represent some object that would contain a cache, such as a
router that maintains a cache of services.
PurgeCache
contains a cache and implements Future
so that it can be
polled as a background task and purge values from the cache when it is able
to.
Both Container
and PurgeCache
contend for a Mutex
that wraps a single
cache. Container
has priority to locking the cache. This is ensured by
Container
blocking when acquiring a lock, and PurgeCache
trying to lock --
scheduling itself to be polled in the near future if it fails.
Access to cache values is maintained through handles to Access
. Access
wraps a Node
and a delay queue expirations
. Node
provides access to an
actual cache value.
The reason a handle is provided to the cache value is because there may be
ongoing access to the value and we want to make sure it is not purged from
the cache by PurgeCache
. When the handle is dropped, Access
resets the
cache value in the delay queue expirations
.
Similarly, we want to be able to add values to the cache, but the value may
not be ready yet. We handle this situation with Reserve
. Reserve
represents a handle to a cache that has capacity for at least one additional
value.