Collection Specs Reference
This page documents the builders used to declare DSM collections.
Collection Identity
All three collection builders start with the same locator parts:
tenantIdapplicationIdcollectionId
Together they form the collection locator. All nodes that should participate in the same logical collection must use the same locator.
Register Collections
Use CollectionSpecBuilder.register(tenantId, applicationId, collectionId) for register-style collections.
Required Fields
schemaId(String)codec(DsmEntityCodec<E>)
Optional Fields
consistencyTier(ConsistencyTier)replicationProfile(ReplicationProfile)qosProfile(QosProfile)persistenceProfile(PersistenceProfile)
Defaults
- consistency tier:
REGISTER - replication profile: embedded register
- QoS profile: best-effort metadata
- persistence profile: ephemeral
Example
CollectionSpec<RouteHint> spec = CollectionSpecBuilder.<RouteHint>register(
"shared",
"gateway",
"route-hints")
.schemaId("route-hints/v1")
.codec(new RouteHintCodec())
.build();Lease Collections
Use LeaseCollectionSpecBuilder.lease(tenantId, applicationId, collectionId) for ownership-sensitive collections.
Required Fields
schemaId(String)codec(DsmEntityCodec<E>)entityFactory(Function<String, E>)
Optional Fields
replicationProfile(ReplicationProfile)qosProfile(QosProfile)persistenceProfile(PersistenceProfile)leaseMode(LeaseMode)leaseTerm(Duration)renewSkew(Duration)expiryGrace(Duration)
Defaults
- replication profile: embedded lease
- QoS profile: control critical
- persistence profile: local durable
- lease mode:
AUTONOMOUS - lease term:
10s - renew skew:
3s - expiry grace:
500ms
Example
LeaseCollectionSpec<ShardOwner> spec = LeaseCollectionSpecBuilder.<ShardOwner>lease(
"shared",
"worker",
"shard-owner")
.schemaId("shard-owner/v1")
.codec(new ShardOwnerCodec())
.entityFactory(ShardOwner::blank)
.leaseTerm(Duration.ofSeconds(10))
.renewSkew(Duration.ofSeconds(3))
.build();Practical Constraints
- the entity factory must be able to create a new blank entity from an entry key
renewSkewshould stay smaller thanleaseTerm- persistence defaults to local durable because lease state is operationally important
CRDT Collections
Use CrdtCollectionSpecBuilder.crdt(tenantId, applicationId, collectionId) for mergeable state.
Required Fields
schemaId(String)codec(DsmEntityCodec<E>)stateCodec(MergeableStateCodec<S>)initialState(S)
Optional Fields
replicationProfile(ReplicationProfile)qosProfile(QosProfile)persistenceProfile(PersistenceProfile)
Defaults
- replication profile: embedded CRDT
- QoS profile: standard
- persistence profile: local durable
Example
CrdtCollectionSpec<PnCounterUpdate, PnCounterState> spec =
CrdtCollectionSpecBuilder.<PnCounterUpdate, PnCounterState>crdt(
"shared",
"billing",
"request-counter")
.schemaId("request-counter/v1")
.codec(new PnCounterUpdateCodec())
.stateCodec(new PnCounterStateCodec())
.initialState(PnCounterState.empty())
.build();The runtime registration call also requires a StateMerger<E, S>.
Profiles
The builders expose three profile dimensions:
Replication Profile
Controls how the collection is replicated by the embedded runtime sync path.
Built-in names used by the Spring path are:
embedded-registerembedded-leaseembedded-crdt
QoS Profile
Controls message delivery characteristics and intended priority.
Built-in names used by the Spring path are:
best-effort-metacontrol-criticalstandard
Persistence Profile
Controls local durability behavior.
Built-in names used by the Spring path are:
ephemerallocal-durable
Schema IDs
schemaId is part of your compatibility contract. Recommended practice:
- change the schema ID when the payload shape or semantics are not safely compatible
- keep the format human-readable, such as
route-hints/v1
Which Builder To Start With
- use register builders first unless you have a clear need for lease or CRDT semantics
- use lease builders for fenced ownership workflows
- use CRDT builders for multi-writer convergent state