aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/relay.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm/relay.rs')
-rw-r--r--src/swarm/relay.rs35
1 files changed, 19 insertions, 16 deletions
diff --git a/src/swarm/relay.rs b/src/swarm/relay.rs
index a8560a5..53c1065 100644
--- a/src/swarm/relay.rs
+++ b/src/swarm/relay.rs
@@ -77,30 +77,33 @@ pub(crate) struct Pending {
}
/// After changes from `from` were applied and our heads changed: passed on at once along
-/// the tree of their `writer` if the message said whose; then announced, in the next
-/// round to those the tree leaves out (to all if there's no tree), and to the others in
-/// the slow round.
-pub(crate) async fn announce(state: &AppState, from: &str, writer: Option<u64>) {
+/// the trees of their `writers` (by their authors' pair keys); then announced, in the
+/// next round to those the trees leave out, and to the others in the slow round. To all
+/// in the next round if any change has no tree to go along: none known whose
+/// (`unauthored`), a writer not in the member list, or we have no part in its tree.
+pub(crate) async fn announce(state: &AppState, from: &str, writers: &[u64], unauthored: bool) {
if !state.initial_sync_done.load(Ordering::Acquire) {
return;
}
- let plan = match writer {
- Some(writer) => crate::swarm::tree::forward(state, writer, from).await,
- None => None,
- };
- let tree = plan.is_some();
+ let mut plans = Vec::new();
+ let mut treeless = unauthored || writers.is_empty();
+ for writer in writers {
+ match crate::swarm::tree::forward(state, *writer, from).await {
+ Some(plan) => plans.push(plan),
+ None => treeless = true,
+ }
+ }
+ let tree = !plans.is_empty();
let schedule = {
let mut pending = state.announce_pending.lock_or_recover();
let schedule = pending.is_none();
let pending = pending.get_or_insert_with(Pending::default);
pending.senders.insert(from.to_owned());
- match &plan {
- Some(plan) => {
- pending.sent.extend(plan.children.iter().cloned());
- pending.targets.extend(plan.uncovered.iter().cloned());
- }
- None => pending.all = true,
+ for plan in &plans {
+ pending.sent.extend(plan.children.iter().cloned());
+ pending.targets.extend(plan.uncovered.iter().cloned());
}
+ pending.all |= treeless;
schedule
};
if schedule {
@@ -115,7 +118,7 @@ pub(crate) async fn announce(state: &AppState, from: &str, writer: Option<u64>)
let slow = slow.get_or_insert_with(Pending::default);
slow.senders.insert(from.to_owned());
slow.all = true;
- if let Some(plan) = &plan {
+ for plan in &plans {
slow.sent.extend(plan.children.iter().cloned());
}
schedule