Skip to content

Commit

Permalink
types.rs, protocol/doh.rs: Completely remove RwLock
Browse files Browse the repository at this point in the history
  • Loading branch information
delta4chat committed Feb 8, 2025
1 parent ab9a14a commit 7a5a459
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 242 deletions.
237 changes: 138 additions & 99 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hitdns"
version = "0.7.0"
version = "0.7.1"
edition = "2021"
description = "hitdns is a DNS forward server optimized for cache hit ratio and query latency."
license = "GPL-3.0"
Expand Down
26 changes: 17 additions & 9 deletions scripts/duplicate-deps.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[syn] =
2.0.90 | 1.0.109
2.0.98 | 1.0.109
================================================

[rand] =
Expand All @@ -11,7 +11,11 @@
================================================

[rustix] =
0.37.27 | 0.38.42
0.37.28 | 0.38.44
================================================

[winnow] =
0.7.1 | 0.6.26
================================================

[polling] =
Expand All @@ -27,15 +31,15 @@
================================================

[bitflags] =
1.3.2 | 2.6.0
1.3.2 | 2.8.0
================================================

[fastrand] =
1.9.0 | 2.3.0
================================================

[getrandom] =
0.1.16 | 0.2.15
0.3.1 | 0.1.16 | 0.2.15
================================================

[hashbrown] =
Expand All @@ -47,34 +51,38 @@
================================================

[thiserror] =
2.0.8 | 1.0.69
1.0.69 | 2.0.11
================================================

[async-lock] =
2.8.0 | 3.4.0
================================================

[smolscale2] =
0.6.0 | 0.5.12
================================================

[rand_chacha] =
0.2.2 | 0.3.1
================================================

[futures-lite] =
2.5.0 | 1.13.0
2.6.0 | 1.13.0
================================================

[async-channel] =
1.9.0 | 2.3.1
================================================

[linux-raw-sys] =
0.3.8 | 0.4.14
0.3.8 | 0.4.15
================================================

[event-listener] =
2.5.3 | 5.3.1
2.5.3 | 5.4.0
================================================

[thiserror-impl] =
2.0.8 | 1.0.69
1.0.69 | 2.0.11
================================================

2 changes: 1 addition & 1 deletion src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ impl HitdnsAPI {
let mut all_metrics = serde_json::Map::new();
for ds in daemon.context.cache.resolvers.list.iter() {
let upstream = ds.dns_upstream();
let mut metrics = ds.dns_metrics().await.to_json();

let mut metrics = ds.dns_metrics().to_json();
{
let obj = metrics.as_object_mut().unwrap();
obj.remove("upstream");
Expand Down
36 changes: 23 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ pub mod dns {
#[cfg(not(feature="doh3"))]
pub use reqwest as reqwest_h3;

pub use portable_atomic::AtomicUsize;

pub use smol::lock::RwLock;
pub use portable_atomic::{AtomicUsize, AtomicU64, AtomicU8, AtomicBool};

pub use bytes::Bytes;
pub use serde::{Serialize, Deserialize};
Expand Down Expand Up @@ -364,17 +362,29 @@ pub fn randstr(len: usize) -> String {
out
}

pub fn average<T>(set: &[T]) -> T
/// u128 nanoseconds version of [core::time::Duration::from_nanos](https://doc.rust-lang.org/1.84.1/src/core/time.rs.html#318-326)
pub const fn duration_from_nanos(nanos: u128) -> Duration {
const NANOS_PER_SEC: u128 = 1_000_000_000;

let secs = (nanos / NANOS_PER_SEC) as u64;
let subsec_nanos = (nanos % NANOS_PER_SEC) as u32;

Duration::new(secs, subsec_nanos)
}

pub fn average<T>(mut iter: impl Iterator<Item=T>, one: T) -> T
where
T: Default + Copy + From<u64> + Add<Output=T> + Div<Output=T>
T: Default + Copy + Ord + Add<Output=T> + Div<Output=T>
{
let len = set.len();
if len > 0 {
let len: T = T::from(len as u64);
let mut sum: T = Default::default();
for n in set.iter() {
sum = sum + *n;
}
let mut len: T = Default::default();
let mut sum: T = Default::default();

while let Some(val) = iter.next() {
sum = sum + val;
len = len + one;
}

if len > Default::default() {
sum / len
} else {
Default::default()
Expand Down Expand Up @@ -861,7 +871,7 @@ impl DNSDaemon {
if opt.debug {
let mut x = vec![];
for r in cache.resolvers.list.iter() {
x.push(r.dns_metrics().await);
x.push(r.dns_metrics());
}

log::trace!(
Expand Down
71 changes: 26 additions & 45 deletions src/protocol/doh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pub(crate) static DOH3_ONLY: AtomicBool = AtomicBool::new(false);
pub struct DNSOverHTTPS {
client: ClientKind,
url: reqwest_h3::Url,
metrics: Arc<RwLock<DNSMetrics>>,
metrics: Arc<DNSMetrics>,
_task: Arc<smol::Task<()>>,
}

Expand Down Expand Up @@ -300,7 +300,7 @@ impl<'a> DNSOverHTTPS {
client = ClientKind::H3(DOH3_CLIENT.clone());
}

let metrics = Arc::new(RwLock::new(DNSMetrics::from(&url)));
let metrics = Arc::new(DNSMetrics::from(&url));

let _task = Arc::new(smolscale2::spawn(
Self::_metrics_task(
Expand All @@ -321,7 +321,7 @@ impl<'a> DNSOverHTTPS {
async fn _metrics_task(
client: ClientKind,
url: reqwest_h3::Url,
metrics: Arc<RwLock<DNSMetrics>>,
metrics: Arc<DNSMetrics>,
) {
let mut start;
let mut latency;
Expand Down Expand Up @@ -352,26 +352,21 @@ impl<'a> DNSOverHTTPS {
.await;
latency = start.elapsed();

let metrics = metrics.clone();
{
let mut m = metrics.write().await;

if let Some(ret) = &maybe_ret {
if ret.is_ok() {
ret.log_trace();
mult = 1.0;
log::debug!("DoH{v} server {} working. latency={latency:?}", &url);
m.up(latency);
} else {
mult *= 1.1;
log::warn!("DoH{v} server {} down. used time: {latency:?}, ret={ret:?}", &url);
m.down();
}
if let Some(ref ret) = maybe_ret {
if ret.is_ok() {
ret.log_trace();
mult = 1.0;
log::debug!("DoH{v} server {} working. latency={latency:?}", &url);
metrics.up(latency);
} else {
mult *= 1.1;
log::warn!("DoH{v} server {} not working! timed out.", &url);
m.down();
log::warn!("DoH{v} server {} down. used time: {latency:?}, ret={ret:?}", &url);
metrics.down();
}
} else {
mult *= 1.1;
log::warn!("DoH{v} server {} not working! timed out.", &url);
metrics.down();
}
}
}
Expand All @@ -386,26 +381,18 @@ impl<'a> DNSOverHTTPS {
let latency = start.elapsed();
log::debug!("DoH{v} un-cached Result: (server={} latency={latency:?}) {result:?}", &self.url);

let ok = result.is_ok();

let metrics_lock = self.metrics.clone();
smolscale2::spawn(async move {
let mut metrics = metrics_lock.write().await;

if ok {
metrics.up(latency);
} else {
metrics.down();
}
}).detach();
if result.is_ok() {
self.metrics.up(latency);
} else {
self.metrics.down();
}

result
}
async fn _orig_dns_resolve(&self, query: &DNSQuery) -> anyhow::Result<dns::Message> {
let v = self.client.version();

let req: dns::Message =
query.try_into().log_warn()?;
let req: dns::Message = query.try_into().log_warn()?;

let client = self.client.clone();
let url = self.url.clone();
Expand Down Expand Up @@ -446,13 +433,9 @@ impl<'a> DNSOverHTTPS {
}

impl DNSResolver for DNSOverHTTPS {
fn dns_resolve(
&self,
query: &DNSQuery,
) -> PinFut<anyhow::Result<dns::Message>> {
let query = query.clone();
Box::pin(async move {
self._dns_resolve(&query).await
fn dns_resolve<'a>(&'a self, query: &'a DNSQuery) -> PinFut<'a, anyhow::Result<dns::Message>> {
Box::pin(async {
self._dns_resolve(query).await
})
}

Expand All @@ -470,9 +453,7 @@ impl DNSResolver for DNSOverHTTPS {
}
}

fn dns_metrics(&self) -> PinFut<DNSMetrics> {
Box::pin(async move {
self.metrics.read().await.clone()
})
fn dns_metrics(&self) -> Arc<DNSMetrics> {
self.metrics.clone()
}
}
4 changes: 2 additions & 2 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub type PinFut<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

pub trait DNSResolver: Send + Sync + 'static {
/// un-cached DNS query
fn dns_resolve(&self, query: &DNSQuery) -> PinFut<anyhow::Result<dns::Message>>;
fn dns_resolve<'a>(&'a self, query: &'a DNSQuery) -> PinFut<'a, anyhow::Result<dns::Message>>;

/// a description for upstream, usually URL or any other.
fn dns_upstream(&self) -> String;
Expand All @@ -13,7 +13,7 @@ pub trait DNSResolver: Send + Sync + 'static {
fn dns_protocol(&self) -> &str;

/// get analysis snapshot for this Upstream
fn dns_metrics(&self) -> PinFut<DNSMetrics>;
fn dns_metrics(&self) -> Arc<DNSMetrics>;
}

impl core::fmt::Debug for dyn DNSResolver {
Expand Down
Loading

0 comments on commit 7a5a459

Please sign in to comment.