Skip to main content

Module data

Module data 

Source
Expand description

Datasource contracts: tenant-scoped pools + read/write splitting.

The framework defines the shape of data access; the app implements it with SQLx, SeaORM, or anything else — the same boundary rule that keeps OAuth providers and session stores app-side. core/ is untouched: the registry is an ordinary DI singleton.

§Hot-path guarantees

  • DataSourceRegistry is frozen at boot: tenant→pool lookup is an immutable HashMap read. No locks.
  • Replica selection inside a DataSource implementation should be a single AtomicUsize round-robin — never a locked list.
  • ReadAfterWritePin is one AtomicBool per request, used to route post-write reads to the primary (replica-lag protection).

§Read-after-write rule

Within one request, after the first Write acquisition every subsequent Read must go to the primary — a replica may not have replayed the write yet. Handlers opt in by creating a ReadAfterWritePin and passing it to DataSourceRegistry::acquire:

let pin = ReadAfterWritePin::new();
let ds  = registry.for_tenant(ctx.tenant());
let w   = registry.acquire(ds, AccessIntent::Write, &pin).await?; // pins
let r   = registry.acquire(ds, AccessIntent::Read,  &pin).await?; // → primary

Modules§

db
Unified database facade — one handle, three ecosystems.
drivers
Driver adapters — each behind its Cargo feature.
migrate
Migration runner uses the SQLx query facade; SeaORM/Diesel ledger support arrives with their facade methods. Database migration lifecycle — versioned, checksummed, lock-guarded.
outbox
Transactional Outbox — reliable event publishing without dual writes.
tx
Request-scoped transactions for #[Transactional].

Structs§

DataError
Classified datasource failure — callers can finally distinguish “retry somewhere else” from “this will never work”, which retry policies, circuit breakers, and replica failover need.
DataSourceRegistry
Frozen tenant→datasource map. Built once at boot, provided via DI, read lock-free on every request.
ReadAfterWritePin
Per-request replica-lag protection: once any Write is acquired through this pin, all subsequent Reads are upgraded to the primary.

Enums§

AccessIntent
Whether the caller intends to read or mutate.
DataErrorKind
Failure classes. #[non_exhaustive]: match with a _ arm.

Traits§

DataSource
One logical database: a primary plus optional read replicas.