ARC 1See Shared StateChapters 1โ€“4

Chapter 2 โ€” Start the First Runtime

Chapter objective: After completing this chapter, a developer can build a single-node DsmRuntime, register route-hints, and explain exactly what a successful local write means.

Learning objectives

  1. Identify the responsibilities of Runtime, membership, and collection spec.
  2. Apply the build, register, start, and close order.
  3. Write and read the first RouteHint.
  4. Distinguish local API success from remote visibility.

Prerequisites

Case progress

The fulfillment gateway publishes fulfillment-primary โ†’ 10.0.0.8:8080. This chapter stores and reads the hint on one node. Network propagation comes later.

Four lifecycle steps

Lifecycle of the first Runtime

DsmRuntimeBuilder assembles the runtime. ClusterMembership supplies node identity and communication. CollectionSpec gives a collection a stable locator and schema. DsmRegister is the business-facing typed handle.

NodeInfo self = new NodeInfo("gateway-a", "127.0.0.1", 19090);
DsmRuntime runtime = DsmRuntimeBuilder.builder()
        .clusterId("fulfillment-local")
        .serviceId("gateway")
        .membership(new StandaloneClusterMembership(self))
        .build();

CollectionSpec<RouteHint> routes =
        CollectionSpecBuilder.<RouteHint>register("demo", "gateway", "route-hints")
                .schemaId("route-hints/v1")
                .recordCodec(RouteHint.class)
                .build();
DsmRegister<RouteHint> register = runtime.register(routes);
runtime.start();

Register collections before startup so the Runtime knows the schema when it enters RUNNING. Call close() after use. Tests and examples should use try/finally or an equivalent resource boundary.

First local commit

register.put(new RouteHint(
        "fulfillment-primary",
        EntityMetadata.empty(),
        "10.0.0.8:8080"));

String address = register.get("fulfillment-primary")
        .orElseThrow()
        .address();

The return from put means that this node accepted the local change. It does not report a replication acknowledgement count or promise that another node can already read the value. Single-node membership creates no remote replica.

Counterexample and fault injection

Treat the Runtime as externally ready before runtime.start(), or omit close(). The first mistake confuses completed configuration with an operational Runtime. The second leaks threads and resources. A successful local get also does not establish cluster-wide agreement.

Experiment

Run the upstream Runtime/REPL example test:

cd submodule/dsm-examples/basic-usage-examples
./mvnw -q -Dtest=DsmReplTest test

The command handler can store and list entries while the test creates and closes the Runtime explicitly. It uses controlled fake peers, so success proves the in-process path only, not real networking.

Experiment acceptance card

Field Content
Command cd submodule/dsm-examples/basic-usage-examples && ./mvnw -q -Dtest=DsmReplTest test
Input or fault Single-node reads/writes and controlled test peers
Observable result All three DsmReplTest cases pass and Runtime closes explicitly
Evidence level E2: fixed-source in-process behavior
Not proven Real networking, production discovery, remote write acknowledgement, or capacity

Review

Next

Chapter 3 divides RouteHint into entry identity, entity fields, metadata, codec, and schema so both sides of replication interpret the same state.