Skip to content

Commit be6c59e

Browse files
author
“ramfox”
committed
feat(iroh): prune old, inactive paths
1 parent 4b6824c commit be6c59e

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

iroh/src/magicsock/endpoint_map/endpoint_state.rs

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ use crate::{
4141

4242
mod guarded_channel;
4343

44-
// TODO: use this
45-
// /// Number of addresses that are not active that we keep around per endpoint.
46-
// ///
47-
// /// See [`EndpointState::prune_direct_addresses`].
48-
// pub(super) const MAX_INACTIVE_DIRECT_ADDRESSES: usize = 20;
44+
/// Number of addresses that are not active that we keep around per endpoint.
45+
///
46+
/// See [`EndpointState::prune_ip_addresses`].
47+
pub(super) const MAX_INACTIVE_IP_ADDRESSES: usize = 20;
4948

50-
// TODO: use this
51-
// /// How long since an endpoint path was last alive before it might be pruned.
52-
// const LAST_ALIVE_PRUNE_DURATION: Duration = Duration::from_secs(120);
49+
/// Max duration of how long ago we learned about this source before we are willing
50+
/// to prune it, if the path for this ip address is inactive.
51+
/// TODO(ramfox): fix this comment it's not clear enough
52+
const LAST_SOURCE_PRUNE_DURATION: Duration = Duration::from_secs(120);
5353

5454
// TODO: use this
5555
// /// The latency at or under which we don't try to upgrade to a better path.
@@ -1372,3 +1372,83 @@ impl Future for OnClosed {
13721372
Poll::Ready(self.conn_id)
13731373
}
13741374
}
1375+
1376+
fn prune_paths(
1377+
paths: &mut FxHashMap<transports::Addr, PathState>,
1378+
pending: &VecDeque<transports::Addr>,
1379+
selected_path: &Option<transports::Addr>,
1380+
open_paths: &Vec<transports::Addr>,
1381+
) {
1382+
let ip_paths: BTreeSet<_> = paths
1383+
.keys()
1384+
.filter(|p| {
1385+
if p.is_ip() {
1386+
return true;
1387+
}
1388+
return false;
1389+
})
1390+
.cloned()
1391+
.collect();
1392+
// if the total number of ip paths is less than the allowed number of inactive
1393+
// paths, just return early;
1394+
if ip_paths.len() < MAX_INACTIVE_IP_ADDRESSES {
1395+
return;
1396+
}
1397+
1398+
let mut protected_paths = std::collections::BTreeSet::new();
1399+
for addr in pending {
1400+
protected_paths.insert(addr.clone());
1401+
}
1402+
if let Some(path) = selected_path {
1403+
protected_paths.insert(path.clone());
1404+
}
1405+
for path in open_paths {
1406+
protected_paths.insert(path.clone());
1407+
}
1408+
1409+
let inactive_paths: Vec<_> = ip_paths.difference(&protected_paths).collect();
1410+
1411+
if inactive_paths.len() < MAX_INACTIVE_IP_ADDRESSES {
1412+
return;
1413+
}
1414+
1415+
let mut keep_paths = Vec::new();
1416+
let now = Instant::now();
1417+
// if the last instance in the source was CONST time ago, it can be pruned
1418+
for (addr, state) in paths {
1419+
if inactive_paths.contains(&&addr) {
1420+
let mut is_expired = true;
1421+
for (_source, instant) in &state.sources {
1422+
// it's been less than LAST_SOURCE_PRUNE_DURATION since we
1423+
// last learned about this source
1424+
if *instant + LAST_SOURCE_PRUNE_DURATION < now {
1425+
is_expired = false;
1426+
break;
1427+
}
1428+
}
1429+
if !is_expired {
1430+
keep_paths.push(addr);
1431+
}
1432+
continue;
1433+
} else {
1434+
keep_paths.push(addr);
1435+
}
1436+
}
1437+
1438+
*paths = paths
1439+
.iter()
1440+
.to_owned()
1441+
.filter(|(addr, _)| keep_paths.contains(addr))
1442+
.map(|(addr, state)| (addr.clone(), state.clone()))
1443+
.collect();
1444+
}
1445+
1446+
#[cfg(test)]
1447+
mod tests {
1448+
use n0_error::Result;
1449+
1450+
#[test]
1451+
fn test_prune_paths() -> Result {
1452+
todo!();
1453+
}
1454+
}

iroh/src/magicsock/endpoint_map/path_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::disco::TransactionId;
1414
///
1515
/// [`transports::Addr`]: super::transports::Addr
1616
/// [`EndpointStateActor::paths`]: super::endpoint_state::EndpointStateActor
17-
#[derive(Debug, Default)]
17+
#[derive(Debug, Default, Clone)]
1818
pub(super) struct PathState {
1919
/// How we learned about this path, and when.
2020
///

0 commit comments

Comments
 (0)