transport: bump QUIC idle timeout + keep-alive for long cargo runs #22
@@ -44,7 +44,18 @@ pub const CLAWSTOR_RPC_ALPN: &[u8] = b"clawstor-rpc/1";
|
|||||||
/// Idle timeout on connection — if no data for this long the connection
|
/// Idle timeout on connection — if no data for this long the connection
|
||||||
/// dies. Short enough to notice partitions, long enough to survive a
|
/// dies. Short enough to notice partitions, long enough to survive a
|
||||||
/// paused laptop.
|
/// paused laptop.
|
||||||
const IDLE_TIMEOUT: Duration = Duration::from_secs(30);
|
/// Field finding 2026-07-12: raised from 30s to 10min because a long
|
||||||
|
/// `cargo build` between the initial connect and the follow-up upload
|
||||||
|
/// would silently kill the QUIC connection on `open_bi`. Cargo builds
|
||||||
|
/// on real workspaces routinely run for minutes; the idle timeout is
|
||||||
|
/// there to detect crashed peers, not to enforce interaction cadence.
|
||||||
|
const IDLE_TIMEOUT: Duration = Duration::from_secs(600);
|
||||||
|
|
||||||
|
/// Field finding 2026-07-12: keep the connection warm with a ping
|
||||||
|
/// every KEEP_ALIVE_INTERVAL — cheap belt-and-braces on top of the
|
||||||
|
/// larger idle window so cargo runs longer than the idle timeout
|
||||||
|
/// still stay dialed.
|
||||||
|
const KEEP_ALIVE_INTERVAL: Duration = Duration::from_secs(15);
|
||||||
|
|
||||||
/// Cap on any single RPC message payload. Ping/pong is tiny; other RPCs
|
/// Cap on any single RPC message payload. Ping/pong is tiny; other RPCs
|
||||||
/// stream larger payloads via streams-of-many-messages. Prevents an
|
/// stream larger payloads via streams-of-many-messages. Prevents an
|
||||||
@@ -441,7 +452,19 @@ impl QuicClient {
|
|||||||
let client_crypto = build_client_crypto(&identity)?;
|
let client_crypto = build_client_crypto(&identity)?;
|
||||||
let quic_crypto = quinn::crypto::rustls::QuicClientConfig::try_from(client_crypto)
|
let quic_crypto = quinn::crypto::rustls::QuicClientConfig::try_from(client_crypto)
|
||||||
.context("wrapping rustls ClientConfig for quinn")?;
|
.context("wrapping rustls ClientConfig for quinn")?;
|
||||||
let client_config = ClientConfig::new(Arc::new(quic_crypto));
|
let mut client_config = ClientConfig::new(Arc::new(quic_crypto));
|
||||||
|
// Field finding 2026-07-12: apply the raised idle timeout + a
|
||||||
|
// keep-alive so a long cargo build between the initial connect
|
||||||
|
// and a follow-up upload doesn't kill the connection.
|
||||||
|
let mut transport = quinn::TransportConfig::default();
|
||||||
|
transport
|
||||||
|
.max_idle_timeout(Some(
|
||||||
|
VarInt::from_u64(IDLE_TIMEOUT.as_millis() as u64)
|
||||||
|
.expect("idle timeout fits u64")
|
||||||
|
.into(),
|
||||||
|
))
|
||||||
|
.keep_alive_interval(Some(KEEP_ALIVE_INTERVAL));
|
||||||
|
client_config.transport_config(Arc::new(transport));
|
||||||
let endpoint = Endpoint::client(bind_addr).context("binding quinn client endpoint")?;
|
let endpoint = Endpoint::client(bind_addr).context("binding quinn client endpoint")?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|||||||
Reference in New Issue
Block a user