node: replace rr interval with heartbeat interval

interval
This commit is contained in:
Luna Yao
2026-04-28 21:23:16 +02:00
parent e527717eef
commit 8cf9d493b8
2 changed files with 14 additions and 20 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ pub static DNS_SERVER_RPC_ADDR: LazyLock<Url> =
pub const DNS_NODE_TTI: Duration = Duration::from_secs(5); pub const DNS_NODE_TTI: Duration = Duration::from_secs(5);
pub const DNS_NODE_RR_INTERVAL: Duration = Duration::from_secs(4); pub const DNS_NODE_HEARTBEAT_INTERVAL: Duration = Duration::from_secs(2);
pub const DNS_NODE_RECONCILE_INTERVAL: Duration = Duration::from_secs(10); pub const DNS_NODE_RECONCILE_INTERVAL: Duration = Duration::from_secs(10);
pub const DNS_SERVER_ELECTION_INTERVAL: Duration = Duration::from_secs(5); pub const DNS_SERVER_ELECTION_INTERVAL: Duration = Duration::from_secs(5);
pub const DNS_PEER_TTI: Duration = Duration::from_secs(3); pub const DNS_PEER_TTI: Duration = Duration::from_secs(3);
+13 -19
View File
@@ -1,6 +1,6 @@
use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtxEvent}; use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtxEvent};
use crate::dns::config::{ use crate::dns::config::{
DNS_NODE_RECONCILE_INTERVAL, DNS_NODE_RR_INTERVAL, DNS_PEER_REFRESH_ATTEMPTS, DNS_NODE_HEARTBEAT_INTERVAL, DNS_NODE_RECONCILE_INTERVAL, DNS_PEER_REFRESH_ATTEMPTS,
DNS_PEER_REFRESH_BACKOFF, DNS_SERVER_ELECTION_INTERVAL, DNS_SERVER_RPC_ADDR, DNS_PEER_REFRESH_BACKOFF, DNS_SERVER_ELECTION_INTERVAL, DNS_SERVER_RPC_ADDR,
}; };
use crate::dns::peer_mgr::DnsPeerMgr; use crate::dns::peer_mgr::DnsPeerMgr;
@@ -15,9 +15,9 @@ use crate::tunnel::tcp::{TcpTunnelConnector, TcpTunnelListener};
use crate::utils::task::CancellableTask; use crate::utils::task::CancellableTask;
use std::io; use std::io;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::{broadcast, Notify}; use tokio::sync::{Notify, broadcast};
use tokio::task::JoinSet; use tokio::task::JoinSet;
use tokio::time::{interval, sleep, sleep_until, Instant, MissedTickBehavior}; use tokio::time::{MissedTickBehavior, interval};
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use tracing::instrument; use tracing::instrument;
use uuid::Uuid; use uuid::Uuid;
@@ -42,6 +42,9 @@ impl DnsNodeRuntime {
#[instrument(skip_all, name = "DnsNode election loop")] #[instrument(skip_all, name = "DnsNode election loop")]
async fn run_election(&self, token: CancellationToken) { async fn run_election(&self, token: CancellationToken) {
let mut election_interval = interval(DNS_SERVER_ELECTION_INTERVAL);
election_interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
loop { loop {
tokio::select! { tokio::select! {
biased; biased;
@@ -50,7 +53,7 @@ impl DnsNodeRuntime {
break; break;
} }
_ = self.elect.notified() => {} _ = self.elect.notified() => {}
_ = sleep(DNS_SERVER_ELECTION_INTERVAL) => {} _ = election_interval.tick() => {}
} }
tracing::info!("trying to become DNS server"); tracing::info!("trying to become DNS server");
@@ -84,14 +87,15 @@ impl DnsNodeRuntime {
#[instrument(skip_all, name = "DnsNode main loop")] #[instrument(skip_all, name = "DnsNode main loop")]
async fn run(&self, token: CancellationToken) { async fn run(&self, token: CancellationToken) {
let mut rpc = StandAloneClient::new(TcpTunnelConnector::new(DNS_SERVER_RPC_ADDR.clone())); let mut rpc = StandAloneClient::new(TcpTunnelConnector::new(DNS_SERVER_RPC_ADDR.clone()));
let mut heartbeat = HeartbeatRequest { let mut heartbeat = HeartbeatRequest {
id: Some(self.id().into()), id: Some(self.id().into()),
..Default::default() ..Default::default()
}; };
let mut last_heartbeat = Instant::now();
let timer = sleep_until(last_heartbeat); let mut heartbeat_interval = interval(DNS_NODE_HEARTBEAT_INTERVAL);
tokio::pin!(timer); heartbeat_interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
let mut reconcile_interval = interval(DNS_NODE_RECONCILE_INTERVAL); let mut reconcile_interval = interval(DNS_NODE_RECONCILE_INTERVAL);
reconcile_interval.set_missed_tick_behavior(MissedTickBehavior::Skip); reconcile_interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
@@ -100,15 +104,6 @@ impl DnsNodeRuntime {
let mut tasks = JoinSet::new(); let mut tasks = JoinSet::new();
loop { loop {
// Dynamic interval: slower if dirty (throttled), faster if clean (fast liveness check)
let next_heartbeat = last_heartbeat
+ if self.mgr.dirty.peek() {
DNS_NODE_RR_INTERVAL
} else {
DNS_NODE_RR_INTERVAL / 4
};
timer.as_mut().reset(next_heartbeat);
tokio::select! { tokio::select! {
biased; biased;
@@ -117,13 +112,11 @@ impl DnsNodeRuntime {
break; break;
} }
_ = &mut timer => { _ = heartbeat_interval.tick() => {
if let Err(error) = self.heartbeat(&mut rpc, &mut heartbeat).await { if let Err(error) = self.heartbeat(&mut rpc, &mut heartbeat).await {
tracing::error!(?error, "heartbeat failed"); tracing::error!(?error, "heartbeat failed");
self.elect.notify_one(); self.elect.notify_one();
} }
last_heartbeat = Instant::now();
} }
_ = reconcile_interval.tick() => { _ = reconcile_interval.tick() => {
@@ -261,6 +254,7 @@ mod tests {
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration; use std::time::Duration;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::time::sleep;
#[derive(Debug)] #[derive(Debug)]
struct RecordingDnsNodeMgr { struct RecordingDnsNodeMgr {