Files
huskies/server/src/crdt_state/state/statics.rs
T

51 lines
1.9 KiB
Rust
Raw Normal View History

2026-04-29 13:53:12 +00:00
//! Broadcast channels and op-tracking statics for the CRDT state layer.
//!
//! Provides the outbound sync channel ([`SYNC_TX`]), the event broadcast
//! channel ([`CRDT_EVENT_TX`]), and the in-memory op journal
//! ([`ALL_OPS`] / [`VECTOR_CLOCK`]) that tracks every applied op for
//! delta-sync.
use std::sync::{Mutex, OnceLock};
use bft_json_crdt::json_crdt::SignedOp;
use tokio::sync::broadcast;
use super::super::VectorClock;
use super::super::hex;
use super::super::types::CrdtEvent;
/// Broadcast channel for CRDT events (stage transitions, etc.).
pub(super) static CRDT_EVENT_TX: OnceLock<broadcast::Sender<CrdtEvent>> = OnceLock::new();
/// Broadcast channel for outbound ops to sync peers.
pub(in crate::crdt_state) static SYNC_TX: OnceLock<broadcast::Sender<SignedOp>> = OnceLock::new();
/// All persisted ops as JSON strings, in causal (insertion) order.
///
/// Pub(crate) so that `crdt_snapshot` can access it for compaction.
pub(crate) static ALL_OPS: OnceLock<Mutex<Vec<String>>> = OnceLock::new();
/// Live vector clock tracking op counts per author.
///
/// Updated in lockstep with `ALL_OPS` — every time an op is appended to the
/// journal, the corresponding author's count is incremented here. This avoids
/// re-parsing all ops when a peer requests `our_vector_clock()`.
pub(crate) static VECTOR_CLOCK: OnceLock<Mutex<VectorClock>> = OnceLock::new();
/// Append an op's JSON to `ALL_OPS` and bump the author's count in `VECTOR_CLOCK`.
///
/// Centralises the bookkeeping that must stay in sync between the two statics.
pub(in crate::crdt_state) fn track_op(signed: &SignedOp, json: String) {
if let Some(all) = ALL_OPS.get()
&& let Ok(mut v) = all.lock()
{
v.push(json);
}
if let Some(vc) = VECTOR_CLOCK.get()
&& let Ok(mut clock) = vc.lock()
{
let author_hex = hex::encode(&signed.author());
*clock.entry(author_hex).or_insert(0) += 1;
}
}