Expand description
Metadata Raft quorum for Crabka.
crabka-raft runs a hand-rolled KIP-595 KRaft consensus engine (the
kraft::KraftController) over Crabka’s storage (crabka_log) and
transport (crabka_client_core). The public entry point is
Controller::start, which spawns the engine, opens a TCP listener serving
the real KIP-595 RPCs (Fetch=1, Vote=52, BeginQuorumEpoch=53,
EndQuorumEpoch=54) plus the Crabka-private observer/forward RPCs, and returns
a ControllerHandle for submitting metadata changes and reading the
current crabka_metadata::MetadataImage.
§Quick start
use crabka_metadata::{MetadataRecord, TopicRecord};
use crabka_raft::{Controller, ControllerConfig};
use std::time::Duration;
use uuid::Uuid;
let dir = tempfile::tempdir()?;
let cfg = ControllerConfig::for_tests(1, dir.path().to_path_buf());
let controller = Controller::start(cfg).await?;
controller
.submit_change(vec![MetadataRecord::V1Topic(TopicRecord {
name: "my-topic".into(),
topic_id: Uuid::new_v4(),
partitions: 3,
replication_factor: 1,
})])
.await?;
assert!(controller.current_image().topic("my-topic").is_some());
controller.shutdown().await;§Capabilities and boundaries
The controller persists and recovers KRaft metadata records, serves and
installs KIP-630 snapshots through FetchSnapshot, publishes the current
metadata image to broker tasks, and exposes Crabka-private submit/fetch RPCs
for broker and observer integration. KIP-853-style observer bootstrap and
auto-join are wired through the broker/controller configuration; the older
handle-level add_learner / change_membership compatibility methods still
return RaftError::Unsupported. Mixed JVM+Crabka controller quorums are
outside this crate’s compatibility target.
Re-exports§
pub use handshake::DuplexStream;pub use handshake::RaftHandshakeError;pub use handshake::RaftListenerHandshake;pub use kraft::MetadataFetchSlice;pub use reconfig::AddVoter;pub use reconfig::ReconfigOutcome;pub use reconfig::RemoveVoter;pub use reconfig::UpdateVoter;
Modules§
- handshake
- Pluggable inbound handshake for the controller listener.
- kraft
- Hand-rolled
KRaftconsensus engine (KIP-595 + KIP-996): a pure, deterministic, sans-IOon_eventstate machine (core) over theQuorumState/Rolemodel, driven by the asynccontroller::KraftControllerover thelog::KraftLogand the real KIP-595transportwire. This is Crabka’s live metadata consensus engine. - reconfig
- KIP-853 reconfiguration coordinator: single-voter add/remove/update with safety guards.
Structs§
- AppData
- What we ask Raft to replicate. A batch of
MetadataRecords sosubmit_changecan group related records (Topic + N Partitions) in a single committed entry. - AppData
Response - Controller
- Zero-sized factory for
ControllerHandles. - Controller
Config - Controller
Handle - Handle returned by
Controller::start. Owns the liveKraftControllerengine and the listener task. Drop is NOT a clean shutdown — callSelf::shutdown(orSelf::cancel) to drain the listener + stop the engine before the runtime is torn down. - Crabka
Metadata Fetch Request - Crabka
Metadata Fetch Response - Crabka
Submit Change Request - Forward-to-leader payload. Body is opaque wincode bytes representing the
Vec<MetadataRecord>to apply; the controller layer owns the serde details so the wire module stays metadata-agnostic. - Crabka
Submit Change Response - Node
- KIP-853 voter node identity used by controller membership.
- Plaintext
Dialer - Default no-op dialer: opens a raw
TcpStreamviaConnection::connect. Used when the broker hasn’t injected anInterBrokerClient-backed dialer (legacy PLAINTEXT path). - Quorum
State - Crabka-native view of the controller’s current quorum state. Surfaced by
ControllerHandle::quorum_statefor the broker’sDescribeQuorumadmin handler so callers don’t depend on engine internals directly. - Snapshot
Slice - A contiguous byte window of the latest metadata
.checkpoint, returned byControllerHandle::read_snapshot_rangeto back the broker’sFetchSnapshothandler.
Enums§
- Bootstrap
Mode - Bootstrap orchestration for a freshly-formatted controller node.
- Raft
Error - Snapshot
Range - Outcome of
ControllerHandle::read_snapshot_range. The broker’sFetchSnapshothandler maps each variant to its Kafka error code:NoSnapshot→SNAPSHOT_NOT_FOUND,OutOfRange→POSITION_OUT_OF_RANGE.
Constants§
- API_
KEY_ METADATA_ FETCH - Observer metadata fetch. The body carries a
fetch_offset(KraftLogoffset) +max_bytes; the response carries committed__cluster_metadataentries encoded as Kafka record batches, pluslog_start_offset/high_watermarkand aleader_hint. - API_
KEY_ SUBMIT_ CHANGE - Forward a
Controller::submit_changefrom a follower to the leader. The body is the wincode-encodedVec<MetadataRecord>; the response carries a singleerror_code(0 = applied, non-zero = not-leader / metadata-validation).
Traits§
- Outbound
Dialer - Outbound dialer the controller hands to the peer sender.