# Quickstart: Namespace Consistency Modes This guide shows how to operate namespace-level consistency (strong vs eventual) now that runtime mode updates are supported. ## Boot a local cluster ```bash # Start three nodes with explicit namespace modes (default=strong, logs=eventual) cargo run -p rdb-server -- --store-id 1 --addr 127.0.0.1:50051 --namespace-mode logs=eventual cargo run -p rdb-server -- --store-id 2 --addr 127.0.0.1:50052 --peer 1=127.0.0.1:50051 --namespace-mode logs=eventual cargo run -p rdb-server -- --store-id 3 --addr 127.0.0.1:50053 --peer 1=127.0.0.1:50051 --namespace-mode logs=eventual ``` ## Inspect current modes `RaftService/GetMode` (single namespace) and `RaftService/ListNamespaceModes` (all namespaces) expose the active configuration and whether a namespace was implicitly created from the default. ```bash # List all namespaces and their modes grpcurl -plaintext 127.0.0.1:50051 raftpb.RaftService/ListNamespaceModes # Check a specific namespace grpcurl -plaintext -d '{"namespace":"logs"}' 127.0.0.1:50051 raftpb.RaftService/GetMode ``` The response includes `from_default=true` when the namespace was auto-created using the default mode. ## Update a namespace mode (rolling safe) Mode updates are applied in-memory and picked up immediately by peers; roll across nodes to avoid divergence. ```bash # Switch "logs" to strong consistency on node 1 grpcurl -plaintext -d '{"namespace":"logs","mode":"strong"}' \ 127.0.0.1:50051 raftpb.RaftService/UpdateNamespaceMode # Repeat on each node; verify all agree grpcurl -plaintext 127.0.0.1:50051 raftpb.RaftService/ListNamespaceModes grpcurl -plaintext 127.0.0.1:50052 raftpb.RaftService/ListNamespaceModes grpcurl -plaintext 127.0.0.1:50053 raftpb.RaftService/ListNamespaceModes ``` If nodes return different modes for the same namespace, treat it as a mismatch and reapply the update on the outlier nodes. ## Client usage (KV) Strong namespaces use CAS/read/write through the Raft leader; eventual namespaces accept `RawPut/RawGet` locally with LWW replication. ```bash # Eventual write/read grpcurl -plaintext -d '{"namespace":"logs","key":"a","value":"b"}' \ 127.0.0.1:50051 kvrpc.KvRaw/RawPut grpcurl -plaintext -d '{"namespace":"logs","key":"a"}' \ 127.0.0.1:50052 kvrpc.KvRaw/RawGet # Strong write/read grpcurl -plaintext -d '{"namespace":"default","key":"a","value":"b","expected_version":0}' \ 127.0.0.1:50051 kvrpc.KvCas/CompareAndSwap grpcurl -plaintext -d '{"namespace":"default","key":"a"}' \ 127.0.0.1:50051 kvrpc.KvCas/Get ``` ## Ops checklist - Use `ListNamespaceModes` to confirm all nodes share the same mode set before traffic. - Apply mode updates namespace-by-namespace on each node (or automate via PD) until `from_default=false` everywhere for configured namespaces. - Keep the default namespace as strong unless explicitly relaxed. ## Verification Run the hardened verify script before committing: ```bash scripts/verify-raft.sh # Expected: cargo fmt clean, all rdb-server tests pass (strong/eventual mode flows) ``` This executes `cargo fmt` and `cargo test -p rdb-server --tests` in the Nix shell with protobuf/libclang prepared.