From e0e4af3e9b436d0707b995f316cc059ae38a77cf Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Thu, 24 Sep 2026 23:14:40 -0700 Subject: [PATCH] fix(supervisor-client): open a fresh connection per request Since 0828cb45df the shared Unix-socket client keeps idle connections for up to 90s, while the supervisor closes an idle keep-alive connection after 15s. A VMM request that picks up a pooled connection as the supervisor closes it fails with EPIPE, surfacing as a GetInfo error. Local socket connects are cheap, so go back to one connection per request. Signed-off-by: Kevin Wang --- dstack/supervisor/client/src/lib.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dstack/supervisor/client/src/lib.rs b/dstack/supervisor/client/src/lib.rs index 53257e5c9..96a219ee8 100644 --- a/dstack/supervisor/client/src/lib.rs +++ b/dstack/supervisor/client/src/lib.rs @@ -5,7 +5,7 @@ use std::{path::Path, sync::Arc, time::Duration}; use anyhow::{Context, Result}; -use http_client::http_request; +use http_client::{http_request_with_options, ConnectionReuse, RequestOptions}; use log::{error, info}; use supervisor::{ProcessConfig, ProcessInfo, Response}; @@ -97,8 +97,15 @@ impl SupervisorClient { "POST" | "PUT" | "PATCH" => serde_json::to_vec(&body)?, _ => vec![], }; + // The supervisor drops an idle keep-alive connection after 15s, so a + // pooled one can be closed under the next request (EPIPE). + let options = RequestOptions { + connection_reuse: ConnectionReuse::Fresh, + ..Default::default() + }; let (status, response_bytes) = - http_request(method, &self.base_url, path, &body_bytes).await?; + http_request_with_options(method, &self.base_url, path, &body_bytes, &[], options) + .await?; if status != 200 { anyhow::bail!("Server returned error: {}", status); }