use notify in dirty states

This commit is contained in:
Luna Yao
2026-02-21 19:25:29 +01:00
parent 3d3dba28e8
commit d3ca03e20e
4 changed files with 36 additions and 8 deletions
+2 -1
View File
@@ -48,6 +48,7 @@ impl DnsClient {
..Default::default() ..Default::default()
}; };
loop { loop {
self.mgr.dirty.notified().await;
if let Err(e) = self.heartbeat(&mut rpc, &mut heartbeat).await { if let Err(e) = self.heartbeat(&mut rpc, &mut heartbeat).await {
tracing::error!("DnsClient heartbeat failed: {:?}", e); tracing::error!("DnsClient heartbeat failed: {:?}", e);
} }
@@ -60,7 +61,7 @@ impl DnsClient {
rpc: &mut StandAloneClient<TcpTunnelConnector>, rpc: &mut StandAloneClient<TcpTunnelConnector>,
heartbeat: &mut HeartbeatRequest, heartbeat: &mut HeartbeatRequest,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let request = if heartbeat.snapshot.is_none() || self.mgr.dirty.reset() { let request = if heartbeat.snapshot.is_none() || self.mgr.dirty.peers.reset() {
heartbeat.update(self.mgr.snapshot()); heartbeat.update(self.mgr.snapshot());
heartbeat.clone().into() heartbeat.clone().into()
} else { } else {
+15 -4
View File
@@ -13,11 +13,12 @@ use crate::proto::rpc_types;
use crate::proto::rpc_types::controller::BaseController; use crate::proto::rpc_types::controller::BaseController;
use crate::utils::DeterministicDigest; use crate::utils::DeterministicDigest;
use anyhow::Context; use anyhow::Context;
use derive_more::Deref; use derive_more::{Deref, DerefMut};
use itertools::Itertools; use itertools::Itertools;
use moka::future::Cache; use moka::future::Cache;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tokio::sync::Notify;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DnsPeerInfo { pub struct DnsPeerInfo {
@@ -39,10 +40,18 @@ impl TryFrom<DnsExportConfig> for DnsPeerInfo {
const DNS_PEER_TTL: Duration = Duration::from_secs(3); const DNS_PEER_TTL: Duration = Duration::from_secs(3);
#[derive(Debug, Default, Deref, DerefMut)]
pub struct DnsPeerMgrDirtyState {
pub(crate) peers: DirtyFlag,
#[deref]
#[deref_mut]
notify: Notify,
}
#[derive(Debug, Deref)] #[derive(Debug, Deref)]
pub struct DnsPeerMgr { pub struct DnsPeerMgr {
peers: Cache<PeerId, DnsPeerInfo>, peers: Cache<PeerId, DnsPeerInfo>,
pub(super) dirty: DirtyFlag, pub(super) dirty: DnsPeerMgrDirtyState,
#[deref] #[deref]
mgr: Arc<PeerManager>, mgr: Arc<PeerManager>,
@@ -53,7 +62,7 @@ impl DnsPeerMgr {
Self { Self {
mgr: peer_mgr.clone(), mgr: peer_mgr.clone(),
peers: Cache::builder().time_to_live(DNS_PEER_TTL).build(), peers: Cache::builder().time_to_live(DNS_PEER_TTL).build(),
dirty: DirtyFlag::new(true), dirty: Default::default(),
} }
} }
@@ -88,6 +97,8 @@ impl DnsPeerMgr {
} }
}; };
self.dirty.peers.mark();
match self.fetch(peer_id).await { match self.fetch(peer_id).await {
Ok(info) => { Ok(info) => {
self.peers.insert(peer_id, info).await; self.peers.insert(peer_id, info).await;
@@ -102,7 +113,7 @@ impl DnsPeerMgr {
} }
} }
self.dirty.mark(); self.dirty.notify_one();
} }
async fn fetch(&self, peer_id: PeerId) -> anyhow::Result<DnsPeerInfo> { async fn fetch(&self, peer_id: PeerId) -> anyhow::Result<DnsPeerInfo> {
+11 -1
View File
@@ -20,8 +20,10 @@ use moka::future::Cache;
use std::collections::HashSet; use std::collections::HashSet;
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use derivative::Derivative; use derivative::Derivative;
use derive_more::{Deref, DerefMut};
use tokio::net::{TcpListener, UdpSocket}; use tokio::net::{TcpListener, UdpSocket};
use tokio::{sync::RwLock, task::JoinHandle}; use tokio::{sync::RwLock, task::JoinHandle};
use tokio::sync::Notify;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use uuid::Uuid; use uuid::Uuid;
@@ -78,11 +80,15 @@ impl RequestHandler for DynamicCatalog {
} }
} }
#[derive(Debug, Default)] // TODO: same as DnsPeerMgrDirtyState
#[derive(Debug, Default, Deref, DerefMut)]
pub struct DnsServerDirtyState { pub struct DnsServerDirtyState {
zones: DirtyFlag, zones: DirtyFlag,
addresses: DirtyFlag, addresses: DirtyFlag,
listeners: DirtyFlag, listeners: DirtyFlag,
#[deref]
#[deref_mut]
notify: Notify,
} }
struct DnsServerRuntime { struct DnsServerRuntime {
@@ -206,6 +212,8 @@ impl DnsServer {
let dirty = &self.dirty; let dirty = &self.dirty;
let mut runtime = None; let mut runtime = None;
loop { loop {
dirty.notified().await;
if dirty.zones.reset() { if dirty.zones.reset() {
self.reload_zones().await; self.reload_zones().await;
} }
@@ -218,6 +226,7 @@ impl DnsServer {
if let Err(e) = self.reload_listeners(&mut runtime).await { if let Err(e) = self.reload_listeners(&mut runtime).await {
tracing::error!("failed to reload listeners: {:?}", e); tracing::error!("failed to reload listeners: {:?}", e);
self.dirty.listeners.mark(); self.dirty.listeners.mark();
self.dirty.notify_one();
} }
} }
@@ -325,6 +334,7 @@ impl DnsServerRpc for DnsServer {
} }
self.clients.insert(id, new).await; self.clients.insert(id, new).await;
self.dirty.notify_one();
} }
false false
} else { } else {
+7 -1
View File
@@ -267,7 +267,7 @@ where
} }
} }
#[derive(Debug, Default)] #[derive(Debug)]
pub(super) struct DirtyFlag(AtomicBool); pub(super) struct DirtyFlag(AtomicBool);
impl DirtyFlag { impl DirtyFlag {
@@ -283,3 +283,9 @@ impl DirtyFlag {
self.0.swap(false, Ordering::Acquire) self.0.swap(false, Ordering::Acquire)
} }
} }
impl Default for DirtyFlag {
fn default() -> Self {
Self::new(true)
}
}