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
The cluster membership (voters + optional learners).
The messaging layer connecting this node to its peers.
Durable state for this node's term, vote, and log.
Timing parameters. Defaults are suitable for LAN; adjust for high-latency or test environments.
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.
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.