mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-03-25 14:11:14 +03:00
Refact. Replace all tokio::time::interval() (#7173)
* Refact. Replace all `tokio::time::interval()` Signed-off-by: fufesou <shuanglongchen@yeah.net> * Refact Better min_interval for `ThrottledInterval`. Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
127
src/common.rs
127
src/common.rs
@@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
future::Future,
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
task::Poll,
|
||||
};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
@@ -132,15 +133,20 @@ use hbb_common::{
|
||||
bytes::Bytes,
|
||||
compress::compress as compress_func,
|
||||
config::{self, Config, CONNECT_TIMEOUT, READ_TIMEOUT},
|
||||
futures_util::future::poll_fn,
|
||||
get_version_number, log,
|
||||
message_proto::*,
|
||||
protobuf::Enum,
|
||||
protobuf::Message as _,
|
||||
protobuf::{Enum, Message as _},
|
||||
rendezvous_proto::*,
|
||||
socket_client,
|
||||
sodiumoxide::crypto::{box_, secretbox, sign},
|
||||
tcp::FramedStream,
|
||||
timeout, tokio, ResultType,
|
||||
timeout,
|
||||
tokio::{
|
||||
self,
|
||||
time::{Duration, Instant, Interval},
|
||||
},
|
||||
ResultType,
|
||||
};
|
||||
// #[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
||||
use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all};
|
||||
@@ -1335,3 +1341,118 @@ pub fn using_public_server() -> bool {
|
||||
&& crate::get_custom_rendezvous_server(get_option("custom-rendezvous-server")).is_empty()
|
||||
}
|
||||
|
||||
pub struct ThrottledInterval {
|
||||
interval: Interval,
|
||||
last_tick: Instant,
|
||||
min_interval: Duration,
|
||||
}
|
||||
|
||||
impl ThrottledInterval {
|
||||
pub fn new(i: Interval) -> ThrottledInterval {
|
||||
let period = i.period();
|
||||
ThrottledInterval {
|
||||
interval: i,
|
||||
last_tick: Instant::now() - period * 2,
|
||||
min_interval: Duration::from_secs_f64(period.as_secs_f64() * 0.9),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn tick(&mut self) -> Instant {
|
||||
loop {
|
||||
let instant = poll_fn(|cx| self.poll_tick(cx));
|
||||
if let Some(instant) = instant.await {
|
||||
return instant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poll_tick(&mut self, cx: &mut std::task::Context<'_>) -> Poll<Option<Instant>> {
|
||||
match self.interval.poll_tick(cx) {
|
||||
Poll::Ready(instant) => {
|
||||
if self.last_tick.elapsed() >= self.min_interval {
|
||||
self.last_tick = Instant::now();
|
||||
Poll::Ready(Some(instant))
|
||||
} else {
|
||||
// This call is required since tokio 1.27
|
||||
cx.waker().wake_by_ref();
|
||||
Poll::Ready(None)
|
||||
}
|
||||
}
|
||||
Poll::Pending => {
|
||||
Poll::Pending
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type RustDeskInterval = ThrottledInterval;
|
||||
|
||||
#[inline]
|
||||
pub fn rustdesk_interval(i: Interval) -> ThrottledInterval {
|
||||
ThrottledInterval::new(i)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::{format::StrftimeItems, Local};
|
||||
use hbb_common::tokio::{
|
||||
self,
|
||||
time::{interval, sleep, Duration},
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_tokio_time_interval() {
|
||||
let mut timer = interval(Duration::from_secs(1));
|
||||
let mut times = Vec::new();
|
||||
sleep(Duration::from_secs(3)).await;
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = timer.tick() => {
|
||||
let format = StrftimeItems::new("%Y-%m-%d %H:%M:%S");
|
||||
times.push(Local::now().format_with_items(format).to_string());
|
||||
if times.len() == 5 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let times2: HashSet<String> = HashSet::from_iter(times.clone());
|
||||
assert_eq!(times.len(), times2.len() + 3);
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[tokio::test]
|
||||
async fn test_RustDesk_interval() {
|
||||
let mut timer = rustdesk_interval(interval(Duration::from_secs(1)));
|
||||
let mut times = Vec::new();
|
||||
sleep(Duration::from_secs(3)).await;
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = timer.tick() => {
|
||||
let format = StrftimeItems::new("%Y-%m-%d %H:%M:%S");
|
||||
times.push(Local::now().format_with_items(format).to_string());
|
||||
if times.len() == 5 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let times2: HashSet<String> = HashSet::from_iter(times.clone());
|
||||
assert_eq!(times.len(), times2.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duration_multiplication() {
|
||||
let dur = Duration::from_secs(1);
|
||||
|
||||
assert_eq!(dur * 2, Duration::from_secs(2));
|
||||
assert_eq!(Duration::from_secs_f64(dur.as_secs_f64() * 0.9), Duration::from_millis(900));
|
||||
assert_eq!(Duration::from_secs_f64(dur.as_secs_f64() * 0.923), Duration::from_millis(923));
|
||||
assert_eq!(Duration::from_secs_f64(dur.as_secs_f64() * 0.923 * 1e-3), Duration::from_micros(923));
|
||||
assert_eq!(Duration::from_secs_f64(dur.as_secs_f64() * 0.923 * 1e-6), Duration::from_nanos(923));
|
||||
assert_eq!(Duration::from_secs_f64(dur.as_secs_f64() * 0.923 * 1e-9), Duration::from_nanos(1));
|
||||
assert_eq!(Duration::from_secs_f64(dur.as_secs_f64() * 0.923 * 1e-10), Duration::from_nanos(0));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user