server: add DnsServerRuntime and event loop

This commit is contained in:
Luna Yao
2026-04-06 11:54:01 +02:00
parent 488dfaf233
commit 5e69a26a53
+60 -12
View File
@@ -16,10 +16,10 @@ use tokio::{
sync::{Mutex, RwLock}, sync::{Mutex, RwLock},
task::JoinHandle, task::JoinHandle,
}; };
use tokio_util::sync::CancellationToken;
use uuid::Uuid; use uuid::Uuid;
use super::{utils::NameServerAddr, zone::Zone}; use super::{utils::NameServerAddr, zone::Zone};
use crate::common::global_ctx::ArcGlobalCtx;
use crate::dns::zone::ZoneGroup; use crate::dns::zone::ZoneGroup;
use crate::proto::dns::DnsSnapshot; use crate::proto::dns::DnsSnapshot;
use crate::proto::rpc_types; use crate::proto::rpc_types;
@@ -90,13 +90,37 @@ pub struct DnsServerDirtyState {
reload: Notify, reload: Notify,
} }
struct DnsServerRuntime {
token: CancellationToken,
task: JoinHandle<()>,
}
impl DnsServerRuntime {
async fn stop(self) -> anyhow::Result<()> {
self.token.cancel();
self.task.await?;
Ok(())
}
fn start<T: RequestHandler>(mut server: ServerFuture<T>) -> Self {
Self {
token: server.shutdown_token().clone(),
task: tokio::spawn(async move {
server
.block_until_done()
.await
.unwrap_or_else(|e| tracing::error!("DNS server exited with error: {:?}", e));
}),
}
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct DnsServer { pub struct DnsServer {
global_ctx: ArcGlobalCtx,
clients: Cache<Uuid, DnsClientInfo>, clients: Cache<Uuid, DnsClientInfo>,
catalog: DynamicCatalog,
server: Arc<Mutex<Option<JoinHandle<()>>>>,
dirty: Arc<DnsServerDirtyState>, dirty: Arc<DnsServerDirtyState>,
catalog: DynamicCatalog,
} }
const DNS_CLIENT_TTL: Duration = Duration::from_secs(5); const DNS_CLIENT_TTL: Duration = Duration::from_secs(5);
@@ -140,7 +164,11 @@ impl DnsServer {
self.catalog.replace(catalog).await; self.catalog.replace(catalog).await;
} }
async fn reload_listeners(&self) { async fn reload_addresses(&self) {
todo!()
}
async fn reload_listeners(&self, runtime: &mut Option<DnsServerRuntime>) -> anyhow::Result<()> {
let listeners = self let listeners = self
.clients .clients
.iter() .iter()
@@ -148,9 +176,8 @@ impl DnsServer {
.flatten() .flatten()
.collect_vec(); .collect_vec();
let mut server = self.server.lock().await; if let Some(old) = runtime.take() {
if let Some(old) = server.take() { old.stop().await?;
old.abort()
} }
let mut new = ServerFuture::new(self.catalog.clone()); let mut new = ServerFuture::new(self.catalog.clone());
@@ -172,11 +199,32 @@ impl DnsServer {
} }
} }
server.replace(tokio::spawn(async move { runtime.replace(DnsServerRuntime::start(new));
if let Err(e) = new.block_until_done().await {
tracing::error!("DNS server exited with error: {:?}", e); Ok(())
}
pub async fn run(&self) {
let dirty = &self.dirty;
let mut runtime = None;
loop {
if dirty.zones.swap(false, Ordering::Acquire) {
self.reload_zones().await;
}
if dirty.addresses.swap(false, Ordering::Acquire) {
self.reload_addresses().await;
}
if dirty.listeners.swap(false, Ordering::Acquire) {
if let Err(e) = self.reload_listeners(&mut runtime).await {
tracing::error!("failed to reload listeners: {:?}", e);
self.dirty.listeners.store(true, Ordering::Relaxed);
}
}
tokio::time::sleep(Duration::from_secs(1)).await;
} }
}));
} }
// pub async fn run(&self) { // pub async fn run(&self) {