Developer Guide
This guide is the design and implementation checklist for teams integrating DSM into a real service boundary. Use it when you need more than a quickstart and want stable patterns for modeling, wiring, testing, and operating the integration.
Integration Model
For most services, the clean architecture is:
- one DSM integration module owns runtime bootstrap
- that module registers collections and holds typed handles
- domain-facing adapters expose business operations, not raw DSM locators
- application code calls those adapters
That pattern keeps DSM semantics explicit without leaking infrastructure details everywhere.
Public Surface You Actually Integrate With
The main public API lives in dsm-core:
DsmRuntimeDsmRuntimeBuilderTenantRuntimeApplicationRuntimeCollectionSpecBuilderLeaseCollectionSpecBuilderCrdtCollectionSpecBuilderDsmRegisterDsmLeaseRegisterDsmCrdtCollection
If you use Spring Boot, the public integration surface adds:
dsm-spring-boot-starterdsm.*configuration properties- bean injection of registered collection handles
Choose The Right Collection Type
Register
Use a register collection when one key maps to one latest logical value and writes are not expected to be independently merged on every node.
Good fits:
- route tables
- shared metadata
- feature flags with an external source of truth
- service discovery hints
Lease
Use a lease collection when ownership matters and you need explicit acquire, renew, transfer, or release semantics.
Good fits:
- shard ownership
- active worker election per key
- fenced processing responsibilities
CRDT
Use a CRDT collection when multiple nodes need local writes and the state must converge through merge semantics.
Good fits:
- counters
- observed-remove sets
- mergeable presence or membership views
If you are unsure, start with a register. It is the cheapest mental model.
Runtime Flow To Design Around
The runtime flow is:
- application code mutates a collection handle
- DSM stamps metadata and records the change in the local runtime
- sync services replicate register, lease, or CRDT deltas to peers
- lagging peers use replay, digest, or snapshot repair paths to converge
This has two practical implications for developers:
- entity codecs and merge semantics must be deterministic across nodes
- collection identity and schema identity must be treated as compatibility boundaries
Entity Design Rules
Prefer Immutable Records
Records fit DSM well because metadata changes produce new values rather than mutating existing objects.
Preserve Entry Keys
entryKey() is the stable per-collection identity. Do not derive it from volatile fields.
Copy Metadata Explicitly
Register and CRDT entities implement withMetadata(...). Lease entities must also preserve lease state through withLeaseState(...) style copying.
Keep Codecs Stable
Two nodes using different binary or structural interpretations of the same schema is a compatibility bug. Treat codec changes as schema changes.
Collection Identity Rules
Every collection is addressed by:
tenantIdapplicationIdcollectionId
Use these as infrastructure identity, not just naming convenience.
Recommended approach:
tenantId: organizational or isolation boundaryapplicationId: service or domain subsystemcollectionId: logical dataset inside that application
Recommended Integration Patterns
Repository-Oriented Wrapper
Wrap a typed DSM handle in a domain-specific adapter and expose business operations.
Centralized Registration
Keep collection registration in one bootstrap location per service. Avoid scattering registration calls across feature packages.
Stable Profiles Per Workload
Only override replication, QoS, or persistence profiles when the workload needs it. The defaults are intentionally aligned to each collection type.
Testing Guidance
The repository favors in-memory collaboration over mock-heavy testing.
Start with these building blocks:
FakeClusterMembershipfromdsm-test-support- standalone runtime wiring from
dsm-examples - integration coverage patterns from
dsm-integration-test
Recommended test layering:
- unit-test entity codecs and wrapper services
- integration-test collection behavior with in-memory membership
- multi-node test key replication and lease ownership changes
Operational Guidance For Developers
Keep Runtime Lifecycle Explicit
The service should know when DSM starts and stops. Hidden lifecycle makes failure analysis harder.
Observe Diagnostics Early
Use runtime and collection diagnostics during rollout, not only after incidents.
Treat Schema IDs As Compatibility Signals
Schema IDs should reflect meaningful payload compatibility, not arbitrary labels.
Which Path To Choose
Use Standalone Wiring When
- your service already has its own bootstrap container
- you want direct control over membership and runtime creation
- you want DSM setup to live in code rather than configuration
Use Spring Boot When
- your platform standardizes on property-driven service configuration
- you want collection handles injected as beans
- you want bootstrap validation of collection definitions and supporting beans