Skip to main content

Module memory

Module memory 

Source
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 BTreeMap keyed by account first, and every list is sorted by the key its trait documents. Two runs over the same writes produce the same lists, so assert_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 a ManualClock, “the card expired” is something a test makes true, not something it waits for.
  • Failure. MemoryStores::fail_next arms a FailurePoint, 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§

ManualClock
A clock that only moves when a test moves it.
MemoryStores
A complete, deterministic set of stores backed by one in-process state.
SystemClock
The wall clock.
UnknownFailurePoint
A name that matches no crash boundary.

Enums§

FailurePoint
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.