refactor: split crdt_sync.rs into auth/wire/server/dispatch/client modules
The 3672-line crdt_sync.rs is split into a sub-module directory with co-located tests per Rust convention: - auth.rs: trusted-keys + bearer-token validation (230 lines) - wire.rs: ChallengeMessage / AuthMessage / SyncMessage types (141 lines) - server.rs: WebSocket server handler (1680 lines) - dispatch.rs: incoming-message dispatch + bulk/clock/op handling (1028 lines) - client.rs: rendezvous client + reconnect/backoff (464 lines) - mod.rs: doc, cross-cutting constants, re-exports (75 lines) No behaviour change. All 65 crdt_sync tests pass; full suite green (2635 tests with --test-threads=1).
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
//! CRDT sync — WebSocket-based replication of pipeline state between huskies nodes.
|
||||
/// WebSocket-based CRDT sync layer for replicating pipeline state between
|
||||
/// huskies nodes.
|
||||
///
|
||||
/// # Protocol
|
||||
///
|
||||
/// ## Version negotiation
|
||||
///
|
||||
/// After the auth handshake, both sides send their first sync message:
|
||||
///
|
||||
/// - **v2 peers** send a `clock` frame: `{"type":"clock","clock":{ <node_id_hex>: <max_count>, ... }}`
|
||||
/// containing a vector clock that maps each author's hex Ed25519 pubkey to the
|
||||
/// count of ops received from that author. Upon receiving the peer's clock,
|
||||
/// each side computes the delta via [`crdt_state::ops_since`] and sends only
|
||||
/// the missing ops as a `bulk` frame.
|
||||
///
|
||||
/// - **v1 (legacy) peers** send a `bulk` frame directly (full op dump).
|
||||
/// A v2 peer receiving a `bulk` first (instead of a `clock`) falls back to
|
||||
/// the full-dump path: applies the incoming bulk and responds with its own
|
||||
/// full bulk. This preserves backward compatibility — no code change needed
|
||||
/// on the v1 side.
|
||||
///
|
||||
/// ## Text frames
|
||||
/// A JSON object with a `"type"` field:
|
||||
/// - `{"type":"clock","clock":{...}}` — Vector clock (v2 protocol).
|
||||
/// - `{"type":"bulk","ops":[...]}` — Ops dump (full or delta).
|
||||
/// - `{"type":"ready"}` — Signals that the bulk-delta phase is complete and the
|
||||
/// sender is ready for real-time op streaming. Locally-generated ops are
|
||||
/// buffered until the peer's `ready` is received, then flushed in order.
|
||||
///
|
||||
/// ## Binary frames (real-time op broadcast)
|
||||
/// Individual `SignedOp`s encoded via [`crate::crdt_wire`] (versioned JSON
|
||||
/// envelope: `{"v":1,"op":{...}}`). Each locally-applied op is immediately
|
||||
/// broadcast as a binary frame to all connected peers.
|
||||
///
|
||||
/// Both the server endpoint and the rendezvous client use the same protocol,
|
||||
/// making the connection fully symmetric.
|
||||
///
|
||||
/// ## Backpressure
|
||||
/// Each connected peer has its own [`tokio::sync::broadcast`] receiver. If a
|
||||
/// slow peer allows the channel to fill (indicated by a `Lagged` error), the
|
||||
/// connection is dropped with a warning log. The peer can reconnect and
|
||||
/// receive a fresh bulk state dump to catch up.
|
||||
|
||||
// ── Cross-cutting constants ─────────────────────────────────────────
|
||||
|
||||
// ── Auth configuration ──────────────────────────────────────────────
|
||||
|
||||
/// Default timeout for the auth handshake (seconds).
|
||||
pub(super) const AUTH_TIMEOUT_SECS: u64 = 10;
|
||||
|
||||
// ── Keepalive configuration ─────────────────────────────────────────
|
||||
|
||||
/// Interval (seconds) between WebSocket Ping frames sent by each side.
|
||||
pub const PING_INTERVAL_SECS: u64 = 30;
|
||||
|
||||
/// Seconds without a Pong response before the connection is dropped.
|
||||
pub const PONG_TIMEOUT_SECS: u64 = 60;
|
||||
|
||||
// ── Sub-modules ─────────────────────────────────────────────────────
|
||||
mod auth;
|
||||
mod client;
|
||||
mod dispatch;
|
||||
mod server;
|
||||
mod wire;
|
||||
|
||||
// ── Public API re-exports ───────────────────────────────────────────
|
||||
pub use auth::{add_join_token, init_token_auth, init_trusted_keys};
|
||||
pub(crate) use client::connect_and_sync;
|
||||
pub use client::{RENDEZVOUS_ERROR_THRESHOLD, spawn_rendezvous_client};
|
||||
pub use server::crdt_sync_handler;
|
||||
|
||||
// Test-only re-export used by `crdt_snapshot` tests.
|
||||
#[cfg(test)]
|
||||
pub(crate) use wire::SyncMessagePublic;
|
||||
Reference in New Issue
Block a user