improvement: make internal gateway clients use the same topology cache (#5191)

This commit is contained in:
Jędrzej Stuczyński
2024-11-29 09:45:12 +00:00
committed by GitHub
parent 56206433e6
commit 889d464e98
2 changed files with 50 additions and 12 deletions
+46 -12
View File
@@ -5,6 +5,8 @@ use async_trait::async_trait;
use nym_sdk::{NymApiTopologyProvider, NymApiTopologyProviderConfig, UserAgent};
use nym_topology::{gateway, NymTopology, TopologyProvider};
use std::sync::Arc;
use std::time::Duration;
use time::OffsetDateTime;
use tokio::sync::Mutex;
use tracing::debug;
use url::Url;
@@ -17,6 +19,7 @@ pub struct GatewayTopologyProvider {
impl GatewayTopologyProvider {
pub fn new(
gateway_node: gateway::LegacyNode,
cache_ttl: Duration,
user_agent: UserAgent,
nym_api_url: Vec<Url>,
) -> GatewayTopologyProvider {
@@ -31,6 +34,9 @@ impl GatewayTopologyProvider {
env!("CARGO_PKG_VERSION").to_string(),
Some(user_agent),
),
cache_ttl,
cached_at: OffsetDateTime::UNIX_EPOCH,
cached: None,
gateway_node,
})),
}
@@ -39,25 +45,53 @@ impl GatewayTopologyProvider {
struct GatewayTopologyProviderInner {
inner: NymApiTopologyProvider,
cache_ttl: Duration,
cached_at: OffsetDateTime,
cached: Option<NymTopology>,
gateway_node: gateway::LegacyNode,
}
impl GatewayTopologyProviderInner {
fn cached_topology(&self) -> Option<NymTopology> {
if let Some(cached_topology) = &self.cached {
if self.cached_at + self.cache_ttl > OffsetDateTime::now_utc() {
return Some(cached_topology.clone());
}
}
None
}
async fn update_cache(&mut self) -> Option<NymTopology> {
let updated_cache = match self.inner.get_new_topology().await {
None => None,
Some(mut base) => {
if !base.gateway_exists(&self.gateway_node.identity_key) {
debug!(
"{} didn't exist in topology. inserting it.",
self.gateway_node.identity_key
);
base.insert_gateway(self.gateway_node.clone());
}
Some(base)
}
};
self.cached_at = OffsetDateTime::now_utc();
self.cached = updated_cache.clone();
updated_cache
}
}
#[async_trait]
impl TopologyProvider for GatewayTopologyProvider {
async fn get_new_topology(&mut self) -> Option<NymTopology> {
let mut guard = self.inner.lock().await;
match guard.inner.get_new_topology().await {
None => None,
Some(mut base) => {
if !base.gateway_exists(&guard.gateway_node.identity_key) {
debug!(
"{} didn't exist in topology. inserting it.",
guard.gateway_node.identity_key
);
base.insert_gateway(guard.gateway_node.clone());
}
Some(base)
}
// check the cache
if let Some(cached) = guard.cached_topology() {
return Some(cached);
}
guard.update_cache().await
}
}
+4
View File
@@ -30,6 +30,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::path::PathBuf;
use std::process;
use std::sync::Arc;
use std::time::Duration;
use tracing::*;
pub(crate) mod client_handling;
@@ -148,8 +149,11 @@ impl<St> Gateway<St> {
}
fn gateway_topology_provider(&self) -> GatewayTopologyProvider {
// TODO: make topology ttl configurable
// (to be done in reeses with the final smooshing)
GatewayTopologyProvider::new(
self.as_topology_node(),
Duration::from_secs(5 * 60),
self.user_agent.clone(),
self.config.gateway.nym_api_urls.clone(),
)