refactor: split crdt_state.rs into 6 sub-modules with co-located tests
The 2122-line crdt_state.rs is split into a sub-module directory: - types.rs: CRDT/view types + CrdtEvent (247 lines) - state.rs: CrdtState struct, statics, init, apply_and_persist (531 lines) - ops.rs: sync API + apply_remote_op + delta-sync tests (455 lines) - write.rs: write_item + bug_511 test (273 lines) - read.rs: read API + dump + dep helpers (469 lines) - presence.rs: node identity + claim API + heartbeat (176 lines) - mod.rs: doc, sub-module decls, re-exports, hex helper (53 lines) Tests are co-located with the code they primarily exercise per Rust convention. No behaviour change. All 26 crdt_state tests pass; full suite green (2635 tests with --test-threads=1).
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
//! CRDT state layer — manages pipeline state as a conflict-free replicated document backed by SQLite.
|
||||
//!
|
||||
//! The CRDT document is the primary source of truth for pipeline item
|
||||
//! metadata (stage, name, agent, etc.). CRDT ops are persisted to SQLite so
|
||||
//! state survives restarts. The filesystem `.huskies/work/` directories are
|
||||
//! still updated as a secondary output for backwards compatibility.
|
||||
//!
|
||||
//! Stage transitions detected by `write_item()` are broadcast as [`CrdtEvent`]s
|
||||
//! so subscribers (auto-assign, WebSocket, notifications) can react without
|
||||
//! polling the filesystem.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// A vector clock mapping node IDs (hex-encoded Ed25519 pubkeys) to the count
|
||||
/// of ops seen from that node. Used for delta sync — a connecting peer sends
|
||||
/// its clock so the other side can compute which ops are missing.
|
||||
pub type VectorClock = HashMap<String, u64>;
|
||||
|
||||
mod ops;
|
||||
mod presence;
|
||||
mod read;
|
||||
mod state;
|
||||
mod types;
|
||||
mod write;
|
||||
|
||||
pub use ops::{all_ops_json, apply_remote_op, ops_since, our_vector_clock, subscribe_ops};
|
||||
pub use presence::{
|
||||
is_claimed_by_us, our_node_id, read_all_node_presence, release_claim, sign_challenge,
|
||||
write_claim, write_node_presence,
|
||||
};
|
||||
pub use read::{
|
||||
CrdtItemDump, CrdtStateDump, check_archived_deps_crdt, check_unmet_deps_crdt,
|
||||
dep_is_archived_crdt, dep_is_done_crdt, dump_crdt_state, evict_item, read_all_items,
|
||||
read_item,
|
||||
};
|
||||
pub use state::init;
|
||||
pub use types::{
|
||||
CrdtEvent, NodePresenceCrdt, NodePresenceView, PipelineDoc, PipelineItemCrdt,
|
||||
PipelineItemView, subscribe,
|
||||
};
|
||||
pub use write::write_item;
|
||||
|
||||
#[cfg(test)]
|
||||
pub use state::init_for_test;
|
||||
|
||||
pub(crate) use state::{ALL_OPS, VECTOR_CLOCK};
|
||||
|
||||
/// Hex-encode a byte slice (no external dep needed).
|
||||
pub(crate) mod hex {
|
||||
pub fn encode(bytes: &[u8]) -> String {
|
||||
bytes.iter().map(|b| format!("{b:02x}")).collect()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user