Expand description
PostgreSQL backend.
Reproduces MemoryStore’s settlement rules exactly — the shared
correctness suite (tests/postgres_suite.rs, mirroring
tollgate-store/tests/store_suite.rs by name) is the proof. Concurrency
control is row-level: SELECT ... FOR UPDATE on the account funds
acquire; on the lease it serializes release/ingest/reclaim against each
other. Fencing tokens come from the account row’s next_fence counter,
so allocation is strictly monotonic per account across any number of
servers sharing the database. Each token remains a capability for its own
lease record; the sequence is not an account-wide validity epoch.
Representation choices (PoC-pragmatic, documented):
- u128 ids as 16-byte
BYTEA(big-endian); - units as
BIGINTwith checked u64↔i64 conversion in both directions (a balance beyond i64::MAX is refused, not wrapped; a negative stored value is refused, not clamped) and schema-level CHECK constraints keeping every unit column non-negative; - lease and credential expiry as floor
BIGINTmicroseconds plus aSMALLINTnanosecond remainder; informational timestamps asBIGINTmicroseconds since the Unix epoch; - snapshots as storage-local
JSONB: ids in the legacy u64 range remain numeric for rollback, larger ids use canonical text, and the public HTTP/Serde contract always uses text.
Snapshot pushes broadcast in-process only; cross-process push
(LISTEN/NOTIFY or the server’s future SSE) is a documented seam in
docs/DESIGN.md.
Structs§
- Pool
Config - Connection-pool bounds. Callers that hold background tasks open against
this store rely on
acquire_timeout: when every connection is checked out by a stalled query, it is the only thing that turns “wait forever” into an error the caller can report (INVARIANTS.md GL-18). - Postgres
Store - Fixture reset is available only in the opt-in
test_supportmodule, never as a method on a normal store handle.