mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-28 04:16:46 -06:00
collab-net: wait longer for one-shot server replies
Publishing uploads a whole file, and a large project on a slow link takes the server several minutes to receive and answer. The one-shot request connections (hosting, the publish upload, a library, a plugin directory) waited the session idle timeout (45s), so a large publish timed out with "no answer from the server" before the server finished. Add a dedicated request_reply_timeout (5m) for these connections, keeping the session idle timeout unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
28de91d9ae
commit
2a08ad3244
@@ -24,6 +24,12 @@ pub struct NetLimits {
|
||||
pub hello_timeout: Duration,
|
||||
/// A connection with no traffic for this long is dead.
|
||||
pub idle_timeout: Duration,
|
||||
/// How long a one-shot request connection (hosting, a library, a plugin directory — and, most
|
||||
/// importantly, publishing a file) waits for the server's reply before giving up. Publishing
|
||||
/// uploads a whole file and a large one on a slow link takes the server a while to receive and
|
||||
/// answer, so this is longer than `idle_timeout` (a large project on a slow connection can
|
||||
/// easily need several minutes).
|
||||
pub request_reply_timeout: Duration,
|
||||
/// A quiet client pings this often (keeps it under `idle_timeout`).
|
||||
pub keepalive: Duration,
|
||||
/// Messages queued for one client before it counts as stuck and is disconnected.
|
||||
@@ -68,6 +74,7 @@ impl Default for NetLimits {
|
||||
burst: 400.0,
|
||||
hello_timeout: Duration::from_secs(10),
|
||||
idle_timeout: Duration::from_secs(45),
|
||||
request_reply_timeout: Duration::from_secs(300),
|
||||
keepalive: Duration::from_secs(15),
|
||||
queue: 1024,
|
||||
write_timeout: Duration::from_secs(10),
|
||||
@@ -85,3 +92,16 @@ impl Default for NetLimits {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn request_reply_wait_is_longer_than_idle() {
|
||||
let d = NetLimits::default();
|
||||
// Publishing uploads a whole file; a slow link must not cut it off at the session idle
|
||||
// timeout. Keep the reply wait comfortably above it.
|
||||
assert!(d.request_reply_timeout > d.idle_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,13 +196,15 @@ pub fn plugins(server: &Endpoint, key: &str, req: PluginReq, limits: &NetLimits,
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
/// A WebSocket to `server` that waits for answers up to the idle timeout (a large upload takes the
|
||||
/// server a while to keep).
|
||||
/// A WebSocket to `server` that waits for answers up to the request-reply timeout (a large upload
|
||||
/// takes the server a while to keep).
|
||||
fn connect(server: &Endpoint, limits: &NetLimits, timeout: Duration) -> Result<Ws, String> {
|
||||
let (stream, _, _) = open(server, timeout, limits)?;
|
||||
let (ws, _) = tungstenite::client::client_with_config(server.url(), stream, Some(config(limits.max_server_message)))
|
||||
.map_err(|e| format!("{} doesn't answer as a FigCraft server: {e}", server.display()))?;
|
||||
ws.get_ref().set_read_timeout(Some(limits.idle_timeout)).map_err(|e| e.to_string())?;
|
||||
// A publish uploads a whole file; a large project on a slow link can take several minutes to
|
||||
// receive and answer. The wait uses `request_reply_timeout`, not the session `idle_timeout`.
|
||||
ws.get_ref().set_read_timeout(Some(limits.request_reply_timeout)).map_err(|e| e.to_string())?;
|
||||
Ok(ws)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user