Expand description
Thread safe traits around implementations of all possible cache store types. They are analogous
to the default traits at the root of this crate but each method has ts_ prepended (Thread
Safe), this allows the thread safe implementations to implement the thread unsafe methods too.
There are a few lifetimes and generics involved in this, so it might be confusing and there was a lot of bodging trying to get it to work, so it’s very likely that there’s something that doesn’t quite work.
There are two classifications of a thread-safe cache store:
- Smart: Means they perform smart logic to allow as much concurrency as possible
- Dumb: Means they aren’t concurrent at all, the simplest example is a wrapper that takes a
CacheStoreand locks it completely for each call, even if they should not interfere. At most, it could implement aRwLockto allow concurrent reads.
To understand this better here are some cases in which a smart store would allow concurrency, a dumb store would block until each thread is done for these examples:
ThreadAreadsA,ThreadBreadsB: A smart store allows both reads to be concurrent. A dumb store with aRwLockcould alloc concurrency in this case.ThreadAwritesA,ThreadBwritesB: A smart store also allows both reads to be concurrent.ThreadAandThreadBwrite toA: The smart store would block untilThreadAis done to allowThreadBto write to it.
Due to this, a smart thread safe store can become a normal CacheStore, and a CacheStore
can become a dumb thread safe cache. But there’s no way to go back, as they “lose” information
on how to handle the store concurrently through these conversions.
§Error Handling
Note that there are not any unfallible cache stores implemented. This is because all thread
safe implementations should work internally through mutexes that when locked, can fail due to a
PoisonError. The unfallible trait is still there in case you want to implement it yourself
through panicking in an error variant or something. It’s HIGHLY discouraged as
PoisonErrors come precisely by panicking on the thread holding the lock, but you decide on
what to do with this after all. For this reason, there’s no default wrapper around it and is
not exported in the prelude.
§Tips
If you want to wrap a CacheStore, they automatically implement TryCacheStore. Such
store will only fail on poison errors, returning a PoisonError with the store lock. You’ll
probably want to use a TryCacheStoreErrorMap to map errors into any kind of error that
implements From<PoisonError<…>>.
If you want to wrap a TryCacheStore, make sure that the error type implements
From<PoisonError<…>> for PoisonErrors.
Modules§
- Thread safe traits for generative cache stores.
Macros§
- A macro to be used by [
ambassador::Delegate] to delegateThreadSafeCacheStore - A macro to be used by [
ambassador::Delegate] to delegateThreadSafeTryCacheStore - Macro to automatically implement
CacheStoreon a struct that implementsThreadSafeCacheStore - Macro to automatically implement
TryCacheStoreon a struct that implementsThreadSafeTryCacheStore
Traits§
- Trait for a thread safe infallible cache store, analogous to CacheStore
- Trait for a thread safe fallible cache store, analogous to []