Expand description
MemoryStores: one deterministic implementation of every persistence
trait, over a single shared state.
It exists for three jobs. It is what tests, examples and the turnframe
facade use when no database is configured. It is the reference an adapter
author reads when the prose in a trait leaves a question open — if
PostgreSQL and this store disagree, one of them is wrong. And it is the
subject the conformance suite is developed against,
so a suite failure means the adapter is wrong rather than the suite.
§What “deterministic” buys
- Order. Every collection is a
BTreeMapkeyed by account first, and every list is sorted by the key its trait documents. Two runs over the same writes produce the same lists, soassert_eq!on a whole list is a fair test rather than a flaky one. - Time. The store never reads the wall clock directly; it asks a
Clock. With aManualClock, “the card expired” is something a test makes true, not something it waits for. - Failure.
MemoryStores::fail_nextarms aFailurePoint, so the recovery paths of spec §27.7 are reachable without killing a process. - Cost. A commit is all-or-nothing without copying the state: the bundle is applied in place and every mutation records how to undo itself, so a failure replays the reversals instead of discarding a clone. A commit costs what it writes, not what the store already holds, which is what keeps a suite of thousands of turns from slowing down as it goes.
§Concurrency
One std::sync::Mutex guards the whole state and a second, independent one
guards the armed failures. Every trait method locks, runs one synchronous
rule function and releases before returning: no guard is ever alive across
an await, which is why these futures are Send at all. A poisoned lock is
reported as StoreError::Corrupt rather than propagating a panic.
§Example
use std::sync::Arc;
use chrono::TimeDelta;
use turnframe_store::memory::{Clock, ManualClock, MemoryStores};
let clock = Arc::new(ManualClock::epoch());
let stores = MemoryStores::with_clock(clock.clone());
assert_eq!(stores.now(), clock.now());
clock.advance(TimeDelta::minutes(5));
assert_eq!(stores.now(), clock.now());Structs§
- Manual
Clock - A clock that only moves when a test moves it.
- Memory
Stores - A complete, deterministic set of stores backed by one in-process state.
- System
Clock - The wall clock.
- Unknown
Failure Point - A name that matches no crash boundary.
Enums§
- Failure
Point - A boundary at which the in-memory store can be made to fail (spec §27.7).
Traits§
- Clock
- Source of the current time for a store.