Skip to content

Commit 201f9d7

Browse files
committed
fix(client): throttle recursive polling during active streams
1 parent 51f030d commit 201f9d7

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

crates/slipstream-client/src/dns/resolver.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub(crate) struct ResolverState {
6262
pub(crate) active_refresh_suspect_count: u8,
6363
pub(crate) active_delete_first_at: u64,
6464
pub(crate) last_progress_at: u64,
65+
pub(crate) last_recursive_poll_sent_at: u64,
6566
}
6667

6768
impl ResolverState {
@@ -143,6 +144,7 @@ impl ResolverManager {
143144
resolver.active_refresh_suspect_count = 0;
144145
resolver.active_delete_first_at = 0;
145146
resolver.last_progress_at = 0;
147+
resolver.last_recursive_poll_sent_at = 0;
146148
}
147149
}
148150

@@ -323,6 +325,7 @@ pub(crate) fn resolve_resolvers(
323325
active_refresh_suspect_count: 0,
324326
active_delete_first_at: 0,
325327
last_progress_at: 0,
328+
last_recursive_poll_sent_at: 0,
326329
});
327330
}
328331
Ok(resolved)
@@ -353,6 +356,7 @@ pub(crate) fn reset_resolver_path(resolver: &mut ResolverState) {
353356
resolver.active_delete_suspect_count = 0;
354357
resolver.active_refresh_suspect_count = 0;
355358
resolver.active_delete_first_at = 0;
359+
resolver.last_recursive_poll_sent_at = 0;
356360
}
357361

358362
pub(crate) fn clear_active_path_suspect(resolver: &mut ResolverState) {

crates/slipstream-client/src/runtime.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,15 @@ pub async fn run_client(config: &ClientConfig<'_>) -> Result<i32, ClientError> {
896896
dns_id: &mut dns_id,
897897
send_buf: &mut send_buf,
898898
};
899-
poll_recursive_resolver(cnx, &mut dispatch, resolver).await?;
899+
poll_recursive_resolver(
900+
cnx,
901+
&mut dispatch,
902+
resolver,
903+
has_ready_stream,
904+
flow_blocked,
905+
sent_quic_data,
906+
)
907+
.await?;
900908
}
901909
}
902910
}

crates/slipstream-client/src/runtime/actions.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ use tracing::debug;
88

99
use super::path::{fetch_path_quality, path_poll_burst_max};
1010

11+
const RECURSIVE_POLL_MIN_INTERVAL_US_ACTIVE: u64 = 5_000;
12+
const RECURSIVE_POLL_MIN_INTERVAL_US_IDLE: u64 = 1_000;
13+
const RECURSIVE_POLL_BURST_ACTIVE_STREAMS: usize = 1;
14+
const RECURSIVE_POLL_BURST_IDLE: usize = 4;
15+
1116
pub(crate) struct PollDispatch<'a, 'cfg> {
1217
pub(crate) udp: &'a TokioUdpSocket,
1318
pub(crate) config: &'a ClientConfig<'cfg>,
@@ -77,6 +82,9 @@ pub(crate) async fn poll_recursive_resolver(
7782
cnx: *mut picoquic_cnx_t,
7883
dispatch: &mut PollDispatch<'_, '_>,
7984
resolver: &mut ResolverState,
85+
has_ready_stream: bool,
86+
flow_blocked: bool,
87+
sent_quic_data: bool,
8088
) -> Result<(), ClientError> {
8189
if resolver.mode != ResolverMode::Recursive {
8290
return Ok(());
@@ -87,7 +95,30 @@ pub(crate) async fn poll_recursive_resolver(
8795
return Ok(());
8896
}
8997

98+
let now = unsafe { slipstream_ffi::picoquic::picoquic_current_time() };
99+
let min_interval = if has_ready_stream {
100+
RECURSIVE_POLL_MIN_INTERVAL_US_ACTIVE
101+
} else {
102+
RECURSIVE_POLL_MIN_INTERVAL_US_IDLE
103+
};
104+
if resolver.last_recursive_poll_sent_at > 0
105+
&& now.saturating_sub(resolver.last_recursive_poll_sent_at) < min_interval
106+
{
107+
return Ok(());
108+
}
109+
110+
if has_ready_stream && !flow_blocked && sent_quic_data {
111+
return Ok(());
112+
}
113+
90114
let burst_max = path_poll_burst_max(resolver);
115+
let burst_cap = if has_ready_stream {
116+
RECURSIVE_POLL_BURST_ACTIVE_STREAMS
117+
} else {
118+
RECURSIVE_POLL_BURST_IDLE
119+
};
120+
let burst_max = burst_max.min(burst_cap.max(1));
121+
let polls_sent_before = resolver.debug.polls_sent;
91122
if resolver.pending_polls > burst_max {
92123
let mut to_send = burst_max;
93124
send_poll_queries(
@@ -121,5 +152,9 @@ pub(crate) async fn poll_recursive_resolver(
121152
resolver.pending_polls = pending;
122153
}
123154

155+
if resolver.debug.polls_sent > polls_sent_before {
156+
resolver.last_recursive_poll_sent_at = now;
157+
}
158+
124159
Ok(())
125160
}

0 commit comments

Comments
 (0)