MongoTimerStore

class MongoTimerStore(client: MongoClient, databaseName: String, context: String, partitions: Int, dispatcher: CoroutineDispatcher = VirtualThreads.dispatcher, ddl: Ddl = Ddl.AUTO, sharding: MongoSharding = MongoSharding.AUTO, operationTimeout: Duration = MongoTimeouts.OPERATION) : TimerStore

The TimerStore of one bounded context on MongoDB: a collection per aggregate type, wow_timer__<context>__<aggregate>, named by the rule of the log's collections, created on the type's first use and recorded in the registry wow_timer_aggregate. One document per timer, keyed by a unique index on its partition, its owner's tenant and id (owner: {tenant_id, id}, its context and aggregate the collection's) and key.

A timer is in its owner's partition, among the partitions of the context's log (Timer.partition). On a sharded cluster each collection is sharded by {partition: 1}, one chunk per partition, spread over the shards while it is new (as the log is): every filter by owner carries the owner's partition, so the reads and writes by owner and the due read of a node's partitions reach the shards of those partitions alone, and the key stays unique across the shards. A retry's read of a target's parked timers (parked) asks every shard.

Every write is one single-document operation, but for cancelAll and settle. A put is a conditional upsert (see conditionalUpsert) whose filter admits only another timer at the same or a later version; a cancel is a conditional update; a settle is one unordered bulk write of conditional updates per collection, each on the document as it was loaded. The due read is one aggregation over the registry: the count of the context's collections, then, through $unionWith, each collection's first due timers over its partial index on (partition, due_at, timer_id) of the PENDING and FIRING (claimed) timers, merged by due time. A count other than the collections read tells the store to read the registry again, so a collection another node created is read at once. The body is kept as the command's JSON text, the rule as a subdocument ({type, ...}, as Wow's JSON writes it). Format 5 is the layout per aggregate type; the timers are a view rebuilt from the log, so a collection of an earlier format is refused, dropped and rebuilt.

Calls run on dispatcher, virtual threads by default.

Constructors

Link copied to clipboard
constructor(client: MongoClient, databaseName: String, context: String, partitions: Int, dispatcher: CoroutineDispatcher = VirtualThreads.dispatcher, ddl: Ddl = Ddl.AUTO, sharding: MongoSharding = MongoSharding.AUTO, operationTimeout: Duration = MongoTimeouts.OPERATION)

Functions

Link copied to clipboard
open suspend override fun cancel(owner: AggregateRef, key: String, version: Long): Boolean
Link copied to clipboard
open suspend override fun cancelAll(owner: AggregateRef, version: Long): Int
Link copied to clipboard
fun collectionName(aggregate: String): String

The name of aggregate's timer collection, wow_timer__<context>__<aggregate>.

Link copied to clipboard

Claims the registry's format; refuses one recorded in another format version (MongoFormat). Each aggregate type's collection is created on its first use.

Link copied to clipboard
open suspend override fun due(partitions: Set<Int>, until: Long, limit: Int): List<Timer>
Link copied to clipboard
open suspend override fun find(owner: AggregateRef, key: String): Timer?
Link copied to clipboard
open suspend override fun parked(target: AggregateRef): List<Timer>
Link copied to clipboard
open suspend override fun put(timer: Timer): Boolean
Link copied to clipboard
open suspend override fun settle(changes: List<TimerChange>): Int