Data Model
DSM models shared state as immutable entities attached to explicit collection locators.
This page defines the shared vocabulary. Use the Reference pages for exact runtime methods, builder defaults, and Spring property names.
Shape Of The Model
Entity Contracts
- Register and CRDT update types implement
DsmEntity<E>. - Lease types implement
LeaseEntity<E>. - The runtime updates metadata by creating a new value object through methods such as
withMetadata(...)orwithLeaseState(...).
This keeps mutation predictable and serialization stable.
Collection Locator
Every collection is addressed by:
tenantIdapplicationIdcollectionId
DSM does not rely on an older namespace compatibility layer. Those identifiers are the address space.
Example:
| Locator | Typical use |
|---|---|
shared/gateway/route-hints | Gateway route metadata. |
shared/worker/shard-owner | Worker ownership leases. |
shared/worker/request-counter | Worker-visible CRDT counters. |
Metadata
Entity metadata is stamped by the runtime and travels with the entity. That metadata is what allows replication and deterministic conflict handling to work across nodes.
Lineage metadata is not optional decoration. Register conflict resolution and lease fencing both rely on it. If a custom merge returns an entity with invalid lineage metadata, the default runtime rejects it rather than letting peers converge on an undefined order.
Immutability
DSM expects immutable value objects, usually Java records. This matters for two reasons:
- replication logic can reason about value identity safely
- codecs can serialize and deserialize entity state without hidden in-place changes
Conflict Handling
Registers use deterministic metadata-driven resolution. Lease collections add fencing semantics. CRDT collections merge toward a convergent state instead of relying on last-writer-wins alone.
Custom register resolvers must be commutative: resolving (A, B) and (B, A) must produce the same semantic winner. Use ConflictResolver.verified(delegate) in tests, staging, or guarded rollout to detect non-commutative behavior before it can create permanent divergence.
Schema Compatibility
schemaId is the human-readable compatibility boundary. RecordCodec also prefixes serialized record payloads with an 8-byte schema fingerprint derived from the record structure. If a remote register upsert carries an incompatible fingerprint, DSM ignores that upsert locally and records a schema mismatch metric instead of crashing the sync path.
Treat this as a rollout safety net, not as a migration strategy. Sustained fingerprint mismatches mean the cluster is running incompatible entity binaries.
Practical Guidance
- Keep entities small and purpose-built.
- Put business payload and runtime metadata side by side in the record.
- Avoid storing large mutable graphs inside DSM entities.
- Treat DSM data as control-plane state, not as your primary application database.
- Change
schemaIdwhen payload semantics are not safely compatible. - Test custom conflict resolvers with reversed input order.