mirror of
https://github.com/threefoldtech/mycelium.git
synced 2026-03-29 07:39:51 +00:00
Skip route selection after unfeasible route update
If an unfeasible update is applied to an existing, unselected route, we now skip route selection altogether. Since the route is not selected, it can obviously not be unselected, and selecting it won't be possible since its now not feasible. By immediately returning we also can't notify downstream peers which have sent a seqno request for this combination. This is fine, since if there is an outstanding request for this seqno, considering it is unfeasible, it won't be of interest to the downstream peer. Note that if the seqno request triggered a bump of the route seqno, the _first_ update is always feasible. Also expose a metric value to track how often we just skip route selection. Closes #329 Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
memory which is not currently used by the cache but still allocated.
|
||||
- Demote seqno cache warnings about duplicate seqno requests go debug lvl, as it
|
||||
is valid to send duplicate requests if sufficient time passed.
|
||||
- Skip route selection after an unfeasible update to a fallback route, as the (now
|
||||
unfeasible) route won't be selected anyway.
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -33,7 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Seqno request cache, to avoid spamming peers with duplicate seqno requests and
|
||||
to make sure seqno's are forwarded to different peers.
|
||||
- Added myceliumd-private binary, which contains private network functionality.
|
||||
- Added API endpoint to retrieve the public key associated with an IP.
|
||||
- Added API endpoint to retrieve the public key associated with an IP.
|
||||
- The CLI can now be used to list, remove or add peers (see `mycelium peers --help`)
|
||||
- The CLI can now be used to list selected and fallback routes (see `mycelium routes --help`)
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ pub struct PrometheusExporter {
|
||||
router_received_tlvs: IntCounter,
|
||||
router_tlv_source_died: IntCounter,
|
||||
router_propage_selected_peers_time_spent: IntCounter,
|
||||
router_update_skipped_route_selection: IntCounter,
|
||||
peer_manager_peer_added: IntCounterVec,
|
||||
peer_manager_known_peers: IntGauge,
|
||||
peer_manager_connection_attemps: IntCounterVec,
|
||||
@@ -125,6 +126,11 @@ impl PrometheusExporter {
|
||||
"Time spent in the propagate_selected_route task, which periodically announces selected routes to peers. Measurement is in nanoseconds",
|
||||
)
|
||||
.expect("Can register an int counter in default registry"),
|
||||
router_update_skipped_route_selection: register_int_counter!(
|
||||
"mycelium_router_update_skipped_route_selection",
|
||||
"Updates which were processed but did not run the route selection step, because the updated route could not be selected anyway",
|
||||
)
|
||||
.expect("Can register an int counter in default registry"),
|
||||
peer_manager_peer_added: register_int_counter_vec!(
|
||||
opts!(
|
||||
"mycelium_peer_manager_peers_added",
|
||||
@@ -363,6 +369,11 @@ impl Metrics for PrometheusExporter {
|
||||
.inc_by(duration.as_nanos() as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn router_update_skipped_route_selection(&self) {
|
||||
self.router_update_skipped_route_selection.inc()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn peer_manager_peer_added(&self, pt: mycelium::peer_manager::PeerType) {
|
||||
let label = match pt {
|
||||
|
||||
@@ -155,6 +155,10 @@ pub trait Metrics {
|
||||
) {
|
||||
}
|
||||
|
||||
/// An update was processed and accepted by the router, but did not run route selection.
|
||||
#[inline]
|
||||
fn router_update_skipped_route_selection(&self) {}
|
||||
|
||||
/// A new [`Peer`](crate::peer::Peer) was added to the
|
||||
/// [`PeerManager`](crate::peer_manager::PeerManager) while it is running.
|
||||
#[inline]
|
||||
|
||||
@@ -972,9 +972,9 @@ where
|
||||
.read()
|
||||
.unwrap()
|
||||
.is_update_feasible(&update);
|
||||
|
||||
// We load all routes here for the subnet. Because we hold the mutex for the
|
||||
// writer, this view is accurate and we can't diverge until the mutex is released.
|
||||
|
||||
let mut routing_table_entries = {
|
||||
if let Some(rte) = self.routing_table.routes_mut(subnet) {
|
||||
rte
|
||||
@@ -1032,6 +1032,16 @@ where
|
||||
existing_entry.set_metric(metric);
|
||||
existing_entry.set_router_id(router_id);
|
||||
existing_entry.set_expires(tokio::time::Instant::now() + route_hold_time(&update));
|
||||
|
||||
// If the route is not selected, and the update is unfeasible, the route will not be
|
||||
// selected by a subsequent route selection, so we can skip it and avoid wasting time
|
||||
// here.
|
||||
if !existing_entry.selected() && !update_feasible {
|
||||
trace!("Ignoring route selection for unfeasible update to unselected route");
|
||||
self.metrics.router_update_skipped_route_selection();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the update is unfeasible the route must be unselected.
|
||||
if existing_entry.selected() && !update_feasible {
|
||||
existing_route_unselected = true;
|
||||
@@ -1041,6 +1051,7 @@ where
|
||||
// If there is no entry yet ignore unfeasible updates and retractions.
|
||||
if metric.is_infinite() || !update_feasible {
|
||||
debug!("Received unfeasible update | retraction for unknown route - neighbour");
|
||||
self.metrics.router_update_skipped_route_selection();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user