Caching docs: Cache is published once, after the pull, so a call makes at most two passes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1ccfe615bc
commit
2db8d72e35
2 changed files with 12 additions and 8 deletions
|
|
@ -144,11 +144,14 @@ which route wrote it.
|
|||
that cache's gate as its own lock, so a store's load callback into the cache
|
||||
cannot take the two out of order; a cacheless store takes its own gate. The
|
||||
store reads which one applies, takes it, and checks the answer again under it:
|
||||
`Cache` is written only by the attach, holding both gates, so under the cache's
|
||||
gate `Cache` naming that cache cannot change, and under the store's gate it
|
||||
cannot change at all. A call whose guess went stale (it queued on a cache that
|
||||
then failed to attach, or on a store that then gained a cache) releases and
|
||||
retries; a cacheless write that finds a cache is refused in that same hold. A
|
||||
`Cache` is written only by the attach, holding both gates, once and after its
|
||||
pull has succeeded (a failed attach never shows it, and nothing detaches), so
|
||||
under the cache's gate `Cache` naming that cache cannot change, and under the
|
||||
store's gate it cannot change at all. The pull reads the registry and the codec
|
||||
the attach lent the store, not `Cache`. A call whose guess went stale (it
|
||||
guessed no cache and the store then gained one) releases and retries once, so a
|
||||
call makes at most two passes; a cacheless write that finds a cache is refused
|
||||
in that same hold. A
|
||||
store must not call `Loaded` while holding its own lock outside the cache's
|
||||
hold.
|
||||
- A journal runs under the cache's gate, so a slow journal slows every writer of
|
||||
|
|
|
|||
|
|
@ -2261,9 +2261,10 @@ namespace GameCult.Caching
|
|||
{
|
||||
if (store == null) throw new ArgumentNullException(nameof(store));
|
||||
homes ??= Array.Empty<Type>();
|
||||
// The only writer of store.Cache, and it writes it only while holding the cache's gate and the store's, the failure path that
|
||||
// resets Cache included: under the cache's gate Cache == this cache cannot change, and under the store's gate Cache cannot
|
||||
// change at all. A store call that guessed wrong waits on whichever gate it took, finds the answer changed and retries.
|
||||
// The only writer of store.Cache, and it writes it once, last, holding the cache's gate and the store's, after the pull has
|
||||
// succeeded: a failed attach never publishes it, and there is no detach, so under the cache's gate Cache == this cache cannot
|
||||
// change, and under the store's gate Cache cannot change at all. A store call that guessed null waits on the store's gate, finds
|
||||
// the cache published and retries once.
|
||||
Held(() => store.UnderStoreGate(() =>
|
||||
{
|
||||
if (store.Cache != null)
|
||||
|
|
|
|||
Loading…
Reference in a new issue