Skip to content

Commit e4f5e32

Browse files
committed
age unneeded relays for a few seconds before closing
This eliminates trash when a relay is closed and then reopened. This also is much less chaotic ...
1 parent 0f8b2b7 commit e4f5e32

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

crates/notedeck/src/subman.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use futures::{channel::mpsc, FutureExt, StreamExt};
22
use std::collections::{BTreeMap, BTreeSet};
33
use std::fmt;
4+
use std::time::{Duration, Instant};
45
use std::{cell::RefCell, cmp::Ordering, rc::Rc};
56
use thiserror::Error;
67
use tracing::{debug, error, info, trace, warn};
@@ -312,6 +313,7 @@ pub struct SubMan {
312313
pool: RelayPool,
313314
local: BTreeMap<LocalId, SubStateRef>,
314315
remote: BTreeMap<RemoteId, SubStateRef>,
316+
idle: BTreeMap<String, Instant>,
315317
}
316318

317319
impl SubMan {
@@ -321,6 +323,7 @@ impl SubMan {
321323
pool,
322324
local: BTreeMap::new(),
323325
remote: BTreeMap::new(),
326+
idle: BTreeMap::new(),
324327
}
325328
}
326329

@@ -688,14 +691,40 @@ impl SubMan {
688691
}
689692
}
690693

694+
const IDLE_EXPIRATION_SECS: Duration = Duration::from_secs(20);
695+
691696
fn close_unneeded_relays(&mut self, default_relays: &[RelaySpec]) {
692697
let current_relays: BTreeSet<String> = self.pool.urls();
693698
let needed_relays: BTreeSet<String> = self.needed_relays(default_relays);
694699
let unneeded_relays: BTreeSet<_> =
695700
current_relays.difference(&needed_relays).cloned().collect();
696-
if !unneeded_relays.is_empty() {
697-
debug!("closing unneeded relays: {:?}", unneeded_relays);
698-
self.pool.remove_urls(&unneeded_relays);
701+
702+
// remove all needed relays from the idle collection
703+
for r in needed_relays {
704+
self.idle.remove(&r);
705+
}
706+
707+
// manage idle relays
708+
let mut expired = BTreeSet::new();
709+
let now = Instant::now();
710+
for r in unneeded_relays {
711+
// could be a new entry, an entry that has only been idle
712+
// a short time, or an expired entry
713+
let entry = self.idle.entry(r.clone()).or_insert(now);
714+
if now.duration_since(*entry) > Self::IDLE_EXPIRATION_SECS {
715+
expired.insert(r.clone());
716+
}
717+
}
718+
719+
// close the expired relays
720+
if !expired.is_empty() {
721+
debug!("closing expired relays: {:?}", expired);
722+
self.pool.remove_urls(&expired);
723+
}
724+
725+
// remove the expired relays from the idle collection
726+
for r in expired {
727+
self.idle.remove(&r);
699728
}
700729
}
701730

0 commit comments

Comments
 (0)