raftNode

fun CoroutineScope.raftNode(clusterConfig: ClusterConfig, transport: RaftTransport, storage: RaftStorage, raftConfig: RaftConfig = RaftConfig(), identity: ClientIdentity = ClientIdentity.Auto, onMetric: (RaftMetric) -> Unit? = null): RaftNode

Creates and starts a RaftNode whose lifetime is tied to this CoroutineScope.

This is the single construction entry point for kuilt-raft. Using a scope extension means the node participates in structured concurrency — it is cancelled automatically when the scope completes or is cancelled, and any exception in the node propagates to the scope's supervisor.

Test-dispatcher guard. If the scope contains a kotlinx.coroutines.test.TestDispatcher, a diagnostic is emitted because real RaftNode uses real-clock kotlinx.coroutines.delay for elections — under virtual time those delays never advance automatically and the test will deadlock silently for the full runTest timeout. Use FakeRaftNode from :kuilt-raft-test for unit tests instead. Set RaftConfig.strictTestGuard to true to throw rather than warn.

Return

A running RaftNode ready to receive proposals and emit committed entries.

Parameters

clusterConfig

The cluster membership (voters + optional learners).

transport

The messaging layer connecting this node to its peers.

storage

Durable state for this node's term, vote, and log.

raftConfig

Timing parameters. Defaults are suitable for LAN; adjust for high-latency or test environments.

identity

How this node obtains its Raft §8 dedup ClientId. ClientIdentity.Auto (default) mints ClientId.auto(thisNodeId, raftConfig.random) — a per-incarnation id giving at-least-once forwarding without cross-crash dedup, re-minted on collision. Pass ClientIdentity.Durable with a stable ClientId the caller persists itself for exactly-once across process restarts (replay the same requestId on retry). See ClientSessionTable.

onMetric

Optional callback invoked on the engine's coroutine at each RaftMetric transition. Use to route metrics to Prometheus, StatsD, OpenTelemetry, or a test assertion. Must not block — the callback runs synchronously on the engine actor; blocking stalls replication for the entire cluster. null (default) disables the hook.