Skip to content

Commit 0d95480

Browse files
authored
Update tunnel_client.rs
## Overview This PR addresses the performance bottlenecks identified in issue #263. As discussed, it moves hardcoded constants related to batching and timeouts into the configuration file. ## Changes - Added `batch_timeout_ms` to config (default: 10000ms). - Added `batch_coalesce_window_ms` to config (default: 8ms). - Added `max_batch_ops` to config (default: 50). - Refactored `tunnel_client.rs` to use these configurable values instead of static constants. ## Impact Users in high-latency environments (like GAS relays) can now tune these parameters to prevent long-tail blocking and improve tunnel responsiveness.
1 parent 901f524 commit 0d95480

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

src/tunnel_client.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,19 @@ const MAX_BATCH_OPS: usize = 50;
4141
/// Timeout for a single batch HTTP round-trip. If the tunnel-node or Apps
4242
/// Script takes longer than this, the batch fails and sessions get error
4343
/// replies rather than hanging forever.
44-
const BATCH_TIMEOUT: Duration = Duration::from_secs(30);
44+
/// const BATCH_TIMEOUT: Duration = Duration::from_secs(30);
4545
4646
/// Timeout for a session waiting for its batch reply. If the batch task
4747
/// is slow (e.g. one op in the batch has a dead target on the tunnel-node
4848
/// side), the session gives up and retries on the next tick rather than
4949
/// blocking indefinitely.
50-
const REPLY_TIMEOUT: Duration = Duration::from_secs(35);
50+
/// const REPLY_TIMEOUT: Duration = Duration::from_secs(35);
5151
5252
/// How long we'll briefly hold the client socket after the local
5353
/// CONNECT/SOCKS5 handshake, waiting for the client's first bytes (the
5454
/// TLS ClientHello for HTTPS). Bundling those bytes with the tunnel-node
5555
/// connect saves one Apps Script round-trip per new flow.
56-
const CLIENT_FIRST_DATA_WAIT: Duration = Duration::from_millis(50);
56+
/// const CLIENT_FIRST_DATA_WAIT: Duration = Duration::from_millis(50);
5757
5858
/// How long the muxer holds open the batch buffer after the first op
5959
/// arrives, waiting for more ops to coalesce. Issue #231 — the previous
@@ -63,7 +63,7 @@ const CLIENT_FIRST_DATA_WAIT: Duration = Duration::from_millis(50);
6363
/// vs the ~2-7 s Apps Script round-trip the batch is amortizing, but
6464
/// long enough that concurrent HTTP/2 stream openings, parallel fetches,
6565
/// or any other burst lands in the same batch.
66-
const BATCH_COALESCE_WINDOW: Duration = Duration::from_millis(8);
66+
/// const BATCH_COALESCE_WINDOW: Duration = Duration::from_millis(8);
6767
6868
/// Structured error code the tunnel-node returns when it doesn't know the
6969
/// op (version mismatch). Must match `tunnel-node/src/main.rs`.
@@ -337,7 +337,7 @@ async fn mux_loop(mut rx: mpsc::Receiver<MuxMsg>, fronter: Arc<DomainFronter>) {
337337
Some(msg) => msgs.push(msg),
338338
None => break,
339339
}
340-
let deadline = tokio::time::Instant::now() + BATCH_COALESCE_WINDOW;
340+
let deadline = tokio::time::Instant::now() + Duration::from_millis(config.batch_coalesce_window_ms);
341341
loop {
342342
// Drain anything that's already queued without waiting.
343343
while let Ok(msg) = rx.try_recv() {
@@ -570,9 +570,16 @@ async fn fire_batch(
570570

571571
// Bounded-wait: if the batch takes longer than BATCH_TIMEOUT,
572572
// all sessions in this batch get an error and can retry.
573+
574+
// let result = tokio::time::timeout(
575+
// BATCH_TIMEOUT,
576+
// f.tunnel_batch_request_to(&script_id, &data_ops),
577+
//)
578+
//.await;
579+
573580
let result = tokio::time::timeout(
574-
BATCH_TIMEOUT,
575-
f.tunnel_batch_request_to(&script_id, &data_ops),
581+
Duration::from_millis(config.batch_timeout_ms),
582+
f.tunnel_batch_request_to(&script_id, &data_ops),
576583
)
577584
.await;
578585
tracing::info!(
@@ -634,7 +641,8 @@ pub async fn tunnel_connection(
634641
} else {
635642
let mut buf = vec![0u8; 65536];
636643
let t0 = Instant::now();
637-
match tokio::time::timeout(CLIENT_FIRST_DATA_WAIT, sock.read(&mut buf)).await {
644+
// match tokio::time::timeout(CLIENT_FIRST_DATA_WAIT, sock.read(&mut buf)).await {
645+
match tokio::time::timeout(Duration::from_millis(config.client_first_data_wait_ms), sock.read(&mut buf)).await {
638646
Ok(Ok(0)) => return Ok(()),
639647
Ok(Ok(n)) => {
640648
mux.record_preread_win(port, t0.elapsed());

0 commit comments

Comments
 (0)