aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/dashboard
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/dashboard')
-rw-r--r--src/api/dashboard/mod.rs38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/api/dashboard/mod.rs b/src/api/dashboard/mod.rs
index dd454ec..f0cbbfd 100644
--- a/src/api/dashboard/mod.rs
+++ b/src/api/dashboard/mod.rs
@@ -10,8 +10,9 @@
//! themselves: they alone changing is no change, and the page counts them on.
//!
//! The map: the graph the member list makes (`topology::intended_graph`, as this node
-//! sees it), and the links every member measures, asked for with LINKS every
-//! `LINKS_EVERY` while anyone looks (`swarm::links`), the same answers for all clients.
+//! sees it), and the links every member measures: subscribed to with LINKS while anyone
+//! looks (renewed every `LINKS_EVERY`, ended when nobody does; `swarm::links`), so a
+//! member tells of a change as it happens; the same answers for all clients.
use std::collections::{BTreeMap, BTreeSet};
use std::convert::Infallible;
@@ -34,10 +35,14 @@ use crate::transport::Link;
/// How often the snapshot is built and compared, while anyone looks.
const TICK: Duration = Duration::from_secs(2);
-/// How often members are asked for their links, and the graph recomputed.
-const LINKS_EVERY: Duration = Duration::from_secs(10);
+/// How often the subscriptions to the members' links are renewed (each renewal is
+/// answered: a reply at least this often), and the graph recomputed; changes come in
+/// between, as they happen (`swarm::links`).
+const LINKS_EVERY: Duration = Duration::from_secs(30);
+/// How long a subscription lasts unless renewed: a node that is gone stops it.
+const LINKS_LEASE: Duration = Duration::from_secs(90);
/// A member's links older than this are left out (it didn't answer since).
-const LINKS_KEPT_FOR: Duration = Duration::from_secs(30);
+const LINKS_KEPT_FOR: Duration = Duration::from_secs(90);
/// The producer runs on this long after the last request for the state.
const LINGER: Duration = Duration::from_secs(60);
/// Members asked for their links at most, each round.
@@ -164,14 +169,27 @@ impl Hub {
if let Some(changed) = document_changes(&mut changes) {
let _ = self.documents.send(Arc::new(changed.to_string()));
}
- {
+ let unwanted = || {
+ self.patches.receiver_count() == 0
+ && Instant::now() >= self.control.lock_or_recover().wanted_until
+ };
+ if *self.closing.borrow() {
+ self.control.lock_or_recover().running = false;
+ return;
+ }
+ if unwanted() {
+ // Nobody looks: the members needn't tell us any more. Unless someone
+ // came meanwhile, then it goes on (and subscribes again).
+ for member in self.state.links.subscribed() {
+ links::unsubscribe(&self.state, &member).await;
+ }
let mut control = self.control.lock_or_recover();
- let unwanted =
- self.patches.receiver_count() == 0 && Instant::now() >= control.wanted_until;
- if unwanted || *self.closing.borrow() {
+ if self.patches.receiver_count() == 0 && Instant::now() >= control.wanted_until {
control.running = false;
return;
}
+ drop(control);
+ graph_due = Instant::now();
}
}
}
@@ -232,7 +250,7 @@ impl Graph {
.take(MAX_ASKED)
{
let state = state.clone();
- tokio::spawn(async move { links::ask(&state, &member).await });
+ tokio::spawn(async move { links::ask(&state, &member, LINKS_LEASE).await });
}
}
}