Skip to content

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:

  1. one DSM integration module owns runtime bootstrap
  2. that module registers collections and holds typed handles
  3. domain-facing adapters expose business operations, not raw DSM locators
  4. 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:

  • DsmRuntime
  • DsmRuntimeBuilder
  • TenantRuntime
  • ApplicationRuntime
  • CollectionSpecBuilder
  • LeaseCollectionSpecBuilder
  • CrdtCollectionSpecBuilder
  • DsmRegister
  • DsmLeaseRegister
  • DsmCrdtCollection

If you use Spring Boot, the public integration surface adds:

  • dsm-spring-boot-starter
  • dsm.* 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:

  1. application code mutates a collection handle
  2. DSM stamps metadata and records the change in the local runtime
  3. sync services replicate register, lease, or CRDT deltas to peers
  4. 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:

  • tenantId
  • applicationId
  • collectionId

Use these as infrastructure identity, not just naming convenience.

Recommended approach:

  • tenantId: organizational or isolation boundary
  • applicationId: service or domain subsystem
  • collectionId: logical dataset inside that application

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:

  • FakeClusterMembership from dsm-test-support
  • standalone runtime wiring from dsm-examples
  • integration coverage patterns from dsm-integration-test

Recommended test layering:

  1. unit-test entity codecs and wrapper services
  2. integration-test collection behavior with in-memory membership
  3. 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

Best Companion Pages