aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/sync.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-31 03:56:30 +0100
committertv <tv@krebsco.de>2026-10-31 03:56:30 +0100
commit0f010a383ae256d7e794c85e4332ee45841625aa (patch)
tree3c1dfb0dc2542bbce1183ae66ca489eef4cedf60 /src/swarm/sync.rs
parent75cc87154b4328758a7d4d6ad76ea2645636530d (diff)
move change publisher to own module
Diffstat (limited to 'src/swarm/sync.rs')
-rw-r--r--src/swarm/sync.rs81
1 files changed, 0 insertions, 81 deletions
diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs
index 05c0c34..e89c2e2 100644
--- a/src/swarm/sync.rs
+++ b/src/swarm/sync.rs
@@ -10,7 +10,6 @@ use tokio::sync::mpsc;
use tokio::time::Instant;
use tracing::{debug, info, trace, warn};
-use crate::document::store::ChangeSet;
use crate::locks::MutexExt;
use crate::state::{AppState, Liveness, PeerState, Standing};
use crate::swarm::peer::{peer_swarm, send_hello_once};
@@ -618,83 +617,3 @@ pub(crate) async fn run_sync_worker(state: AppState, mut rx: mpsc::UnboundedRece
}
}
}
-
-// --- change publisher --------------------------------------------------------
-
-fn patch_store_path(patch: &automerge::Patch) -> Vec<String> {
- let mut path: Vec<String> = patch
- .path
- .iter()
- .map(|(_, prop)| match prop {
- automerge::Prop::Map(key) => key.clone(),
- automerge::Prop::Seq(index) => index.to_string(),
- })
- .collect();
-
- match &patch.action {
- automerge::PatchAction::PutMap { key, .. }
- | automerge::PatchAction::DeleteMap { key, .. } => path.push(key.clone()),
- // List, text and counter changes: the containing object changed.
- _ => {}
- }
- path
-}
-
-pub(crate) async fn run_change_publisher(state: AppState) {
- let mut changed = state.change_tx.subscribe();
- let mut last_heads = state.write_doc(|doc| doc.get_heads()).await;
-
- info!("Starting change publisher");
-
- while changed.changed().await.is_ok() {
- let before = last_heads.clone();
-
- let (heads, paths, conflicts) = state
- .write_doc(move |doc| {
- let heads = doc.get_heads();
- if heads == before {
- return (heads, Vec::new(), Vec::new());
- }
-
- // After an epoch switch the previous heads belong to the old document:
- // report the root as changed, which every stream is related to.
- if !before.iter().all(|h| doc.get_change_by_hash(h).is_some()) {
- return (heads, vec![Vec::new()], Vec::new());
- }
-
- let mut paths = Vec::new();
- let mut conflicts = Vec::new();
- for patch in doc.diff(&before, &heads) {
- let path = patch_store_path(&patch);
- if matches!(
- patch.action,
- automerge::PatchAction::PutMap { conflict: true, .. }
- ) {
- conflicts.push(path.clone());
- }
- paths.push(path);
- }
- (heads, paths, conflicts)
- })
- .await;
-
- if heads == last_heads {
- continue;
- }
- last_heads = heads;
-
- for path in &conflicts {
- warn!(path = ?path, "Concurrent writes produced a conflict");
- }
-
- if paths
- .iter()
- .any(|path| crate::swarm::topology::affects_neighbours(path))
- {
- state.topology_changed.notify_one();
- }
-
- // Fails only when nobody is subscribed.
- let _ = state.change_events.send(Arc::new(ChangeSet { paths }));
- }
-}