PostgresReservationStore

class PostgresReservationStore(dataSource: DataSource, clock: Clock = Clock.systemUTC(), dispatcher: CoroutineDispatcher = VirtualThreads.dispatcher, ddl: Ddl = Ddl.AUTO) : ReservationStore

The ReservationStore on PostgreSQL (documentation/designs/01-programming-model.md §7), in the same database as the log: one table per aggregate type, wow_reservation__<context>__<aggregate>, created with its format record on the type's first use, as the log's and the snapshots' tables are; in it one row per reserved key, keyed by (tenant_id, namespace, key), its owner in two columns and the holds of a pending reservation in a text[] (PostgresReservationTables).

A reserve, a confirm and a release are each one autocommitted statement; a reserve or a confirm is an upsert whose conflict condition admits only the key's owner or an expired pending reservation. An abandon removes its hold and frees a reservation left without holds in one short transaction, the row locked by the first statement. Expiry is judged by clock, not by the database's clock, so it behaves the same in memory and here.

JDBC calls run on dispatcher, virtual threads by default (JDK 21).

Constructors

Link copied to clipboard
constructor(dataSource: DataSource, clock: Clock = Clock.systemUTC(), dispatcher: CoroutineDispatcher = VirtualThreads.dispatcher, ddl: Ddl = Ddl.AUTO)

Functions

Link copied to clipboard
open suspend override fun abandon(scope: ReservationScope, key: String, owner: AggregateRef, hold: String): Boolean
Link copied to clipboard
open suspend override fun confirm(scope: ReservationScope, key: String, owner: AggregateRef, version: Int): ConfirmOutcome
Link copied to clipboard

Nothing to create up front: each aggregate type's table is created on its first use, since the store does not know the aggregate types. Kept for the host, which calls it at startup.

Link copied to clipboard
open suspend override fun find(scope: ReservationScope, key: String): Reservation?
Link copied to clipboard
open suspend override fun release(scope: ReservationScope, key: String, owner: AggregateRef, version: Int): Boolean
Link copied to clipboard
open suspend override fun reserve(scope: ReservationScope, key: String, owner: AggregateRef, hold: String, ttl: Duration): Reservation?