routing table editing atomic

This commit is contained in:
John Smith
2022-09-22 20:25:39 -04:00
parent d160344a77
commit 51b509221c
7 changed files with 224 additions and 170 deletions

View File

@@ -192,11 +192,6 @@ impl RoutingTable {
Self::with_routing_domain(&*inner, domain, |rd| rd.relay_node())
}
pub fn set_relay_node(&self, domain: RoutingDomain, opt_relay_node: Option<NodeRef>) {
let mut inner = self.inner.write();
Self::with_routing_domain_mut(&mut *inner, domain, |rd| rd.set_relay_node(opt_relay_node));
}
pub fn has_dial_info(&self, domain: RoutingDomain) -> bool {
let inner = self.inner.read();
Self::with_routing_domain(&*inner, domain, |rd| !rd.dial_info_details().is_empty())
@@ -299,46 +294,6 @@ impl RoutingTable {
RoutingDomainEditor::new(self.clone(), domain)
}
#[instrument(level = "debug", skip(self), err)]
pub fn register_dial_info(
&self,
domain: RoutingDomain,
dial_info: DialInfo,
class: DialInfoClass,
) -> EyreResult<()> {
if !self.ensure_dial_info_is_valid(domain, &dial_info) {
return Err(eyre!(
"dial info '{}' is not valid in routing domain '{:?}'",
dial_info,
domain
));
}
let mut inner = self.inner.write();
Self::with_routing_domain_mut(&mut *inner, domain, |rd| {
rd.add_dial_info_detail(DialInfoDetail {
dial_info: dial_info.clone(),
class,
});
});
info!(
"{:?} Dial Info: {}",
domain,
NodeDialInfo {
node_id: NodeId::new(inner.node_id),
dial_info
}
.to_string(),
);
debug!(" Class: {:?}", class);
Self::reset_all_seen_our_node_info(&mut *inner, domain);
Self::reset_all_updated_since_last_network_change(&mut *inner);
Ok(())
}
fn reset_all_seen_our_node_info(inner: &mut RoutingTableInner, routing_domain: RoutingDomain) {
let cur_ts = intf::get_timestamp();
Self::with_entries(&*inner, cur_ts, BucketEntryState::Dead, |_, v| {
@@ -357,18 +312,6 @@ impl RoutingTable {
});
}
pub fn clear_dial_info_details(&self, routing_domain: RoutingDomain) {
trace!("clearing dial info domain: {:?}", routing_domain);
let mut inner = self.inner.write();
Self::with_routing_domain_mut(&mut *inner, routing_domain, |rd| {
rd.clear_dial_info_details();
});
// Public dial info changed, go through all nodes and reset their 'seen our node info' bit
Self::reset_all_seen_our_node_info(&mut *inner, routing_domain);
}
pub fn get_own_peer_info(&self, routing_domain: RoutingDomain) -> PeerInfo {
PeerInfo::new(
NodeId::new(self.node_id()),
@@ -858,9 +801,6 @@ impl RoutingTable {
let mut dead = true;
if let Some(nr) = self.lookup_node_ref(*e) {
if let Some(last_connection) = nr.last_connection() {
out.push((*e, RecentPeersEntry { last_connection }));
dead = false;
}

View File

@@ -1,11 +1,17 @@
use super::*;
enum RoutingDomainChange {}
enum RoutingDomainChange {
ClearDialInfoDetails,
ClearRelayNode,
SetRelayNode { relay_node: NodeRef },
AddDialInfoDetail { dial_info_detail: DialInfoDetail },
}
pub struct RoutingDomainEditor {
routing_table: RoutingTable,
routing_domain: RoutingDomain,
changes: Vec<RoutingDomainChange>,
send_node_info_updates: bool,
}
impl RoutingDomainEditor {
@@ -14,8 +20,111 @@ impl RoutingDomainEditor {
routing_table,
routing_domain,
changes: Vec::new(),
send_node_info_updates: true,
}
}
#[instrument(level = "debug", skip(self))]
pub fn disable_node_info_updates(&mut self) {
self.send_node_info_updates = false;
}
pub fn commit(self) {}
#[instrument(level = "debug", skip(self))]
pub fn clear_dial_info_details(&mut self) {
self.changes.push(RoutingDomainChange::ClearDialInfoDetails);
}
#[instrument(level = "debug", skip(self))]
pub fn clear_relay_node(&mut self) {
self.changes.push(RoutingDomainChange::ClearRelayNode);
}
#[instrument(level = "debug", skip(self))]
pub fn set_relay_node(&mut self, relay_node: NodeRef) {
self.changes
.push(RoutingDomainChange::SetRelayNode { relay_node })
}
#[instrument(level = "debug", skip(self), err)]
pub fn register_dial_info(
&mut self,
dial_info: DialInfo,
class: DialInfoClass,
) -> EyreResult<()> {
if !self
.routing_table
.ensure_dial_info_is_valid(self.routing_domain, &dial_info)
{
return Err(eyre!(
"dial info '{}' is not valid in routing domain '{:?}'",
dial_info,
self.routing_domain
));
}
self.changes.push(RoutingDomainChange::AddDialInfoDetail {
dial_info_detail: DialInfoDetail {
dial_info: dial_info.clone(),
class,
},
});
Ok(())
}
#[instrument(level = "debug", skip(self))]
pub async fn commit(self) {
let mut changed = false;
{
let mut inner = self.routing_table.inner.write();
let inner = &mut *inner;
let node_id = inner.node_id;
RoutingTable::with_routing_domain_mut(inner, self.routing_domain, |detail| {
for change in self.changes {
match change {
RoutingDomainChange::ClearDialInfoDetails => {
debug!("[{:?}] cleared dial info details", self.routing_domain);
detail.clear_dial_info_details();
changed = true;
}
RoutingDomainChange::ClearRelayNode => {
debug!("[{:?}] cleared relay node", self.routing_domain);
detail.set_relay_node(None);
changed = true;
}
RoutingDomainChange::SetRelayNode { relay_node } => {
debug!("[{:?}] set relay node: {}", self.routing_domain, relay_node);
detail.set_relay_node(Some(relay_node));
changed = true;
}
RoutingDomainChange::AddDialInfoDetail { dial_info_detail } => {
debug!(
"[{:?}] add dial info detail: {:?}",
self.routing_domain, dial_info_detail
);
detail.add_dial_info_detail(dial_info_detail.clone());
info!(
"{:?} Dial Info: {}",
self.routing_domain,
NodeDialInfo {
node_id: NodeId::new(node_id),
dial_info: dial_info_detail.dial_info
}
.to_string(),
);
changed = true;
}
}
}
});
if changed {
RoutingTable::reset_all_seen_our_node_info(inner, self.routing_domain);
RoutingTable::reset_all_updated_since_last_network_change(inner);
}
}
if changed && self.send_node_info_updates {
let network_manager = self.routing_table.unlocked_inner.network_manager.clone();
network_manager
.send_node_info_updates(self.routing_domain, true)
.await;
}
}
}