kevy_replicate/lib.rs
1//! kevy-replicate — primary-to-replica streaming replication.
2//!
3//! Phase 1 of the v3-cluster series: one primary streams every applied
4//! mutation to N read replicas over a long-lived TCP connection, using a
5//! RESP3-extended frame format with an offset envelope. New replicas join
6//! via an inline snapshot ship, then catch up from the live frame stream.
7//!
8//! - [`wire`] — RESP-based frame format (see `docs/wire.md`).
9//! - [`source`] — primary-side bounded backlog indexed by offset.
10//! - [`handshake`] — `REPLICATE FROM <offset> ID <id>` parse + `+ACK` format.
11//! - [`slot`] — per-replica state + reconnect-window expiry.
12//! - [`replica`] — replica-side blocking TCP client (handshake +
13//! frame-decoding iterator). Snapshot-ship modules land in
14//! subsequent tasks of plan
15//! `.claude/plans/2026-06-18-v3-cluster-plan.md`.
16//!
17//! # Applying replicated frames (T1.19)
18//!
19//! `ReplicaClient` yields decoded `(offset, Argv)` tuples; *applying*
20//! them to a local store is the caller's responsibility — the right
21//! dispatcher depends on where the replica's data lives. The wire
22//! format intentionally carries the exact RESP argv the primary
23//! applied, so any dispatcher that hands `Argv` through Redis-verb
24//! routing produces a byte-equivalent local store.
25//!
26//! The canonical in-process recipe — drop into a fresh
27//! `kevy::KeyspaceStore` and call `kevy::dispatch`:
28//!
29//! ```ignore
30//! use kevy_replicate::replica::ReplicaClient;
31//! let mut client = ReplicaClient::connect(("primary:16004"), "replica-a", 0)?;
32//! let mut store = kevy::KeyspaceStore::new();
33//! for result in &mut client {
34//! let frame = result?;
35//! kevy::dispatch(&mut store, &frame.argv);
36//! }
37//! # Ok::<_, kevy_replicate::replica::ReplicaError>(())
38//! ```
39//!
40//! See the `replica_apply_dispatch_mirrors_primary_store` integration
41//! test in `crates/kevy/tests/replication.rs` for the pattern under
42//! the full primary+replica end-to-end harness.
43//!
44//! Full **server-as-replica** mode (the kevy binary auto-spawns a
45//! per-shard `ReplicaClient` when `[replication] role = "replica"`,
46//! routing frames into the reactor via the cross-shard ring with
47//! re-replication suppression) is Phase 1.F work (T1.28-30). v1.18.0
48//! supports the in-process recipe above for any user that wants to
49//! drive replication themselves.
50#![forbid(unsafe_code)]
51#![warn(missing_docs)]
52
53pub mod handshake;
54pub mod replica;
55mod replica_decode;
56pub mod slot;
57pub mod source;
58pub mod wire;
59mod wire_snapshot;