Skip to content

Commit 68adae5

Browse files
venkyt-aristasylvestre
authored andcommitted
fix: use single-threaded tokio runtime in sccache client
The sccache client was using Runtime::new() which creates a multi-threaded tokio runtime with worker threads equal to the number of CPU cores. On high-core-count servers running many parallel builds, this created an excessive number of threads. For example: - 96 vCPU server - 10 concurrent make invocations - Each make using -j16 - Result: 96 × 10 × 16 = 15,360 threads created by sccache wrappers While these threads are short-lived, with continuous build pipelines this constant thread creation/destruction causes unnecessary overhead. The sccache client only performs simple I/O operations (connecting to server, sending requests, receiving responses) and doesn't need worker threads. This change replaces all client-side Runtime::new() calls with Builder::new_current_thread().enable_all().build() to use a single-threaded runtime, reducing thread count from num_cpus to 1 per client invocation.
1 parent 1e2f32a commit 68adae5

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/commands.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ fn run_server_process(startup_timeout: Option<Duration>) -> Result<ServerStartup
9292
trace!("run_server_process");
9393
let tempdir = tempfile::Builder::new().prefix("sccache").tempdir()?;
9494
let socket_path = tempdir.path().join("sock");
95-
let runtime = Runtime::new()?;
95+
let runtime = tokio::runtime::Builder::new_current_thread()
96+
.enable_all()
97+
.build()?;
9698
let exe_path = env::current_exe()?;
9799
let workdir = exe_path.parent().expect("executable path has no parent?!");
98100

@@ -190,7 +192,9 @@ fn run_server_process(startup_timeout: Option<Duration>) -> Result<ServerStartup
190192
trace!("run_server_process");
191193

192194
// Create a mini event loop and register our named pipe server
193-
let runtime = Runtime::new()?;
195+
let runtime = tokio::runtime::Builder::new_current_thread()
196+
.enable_all()
197+
.build()?;
194198
let pipe_name = &format!(r"\\.\pipe\{}", Uuid::new_v4().as_simple());
195199

196200
// Spawn a server which should come back and connect to us
@@ -627,7 +631,9 @@ pub fn run_command(cmd: Command) -> Result<i32> {
627631
// If there is no server, spawning a new server would start with zero stats
628632
// anyways, so we can just return (mostly) empty stats directly.
629633
Err(_) => {
630-
let runtime = Runtime::new()?;
634+
let runtime = tokio::runtime::Builder::new_current_thread()
635+
.enable_all()
636+
.build()?;
631637
let storage = storage_from_config(config, runtime.handle()).ok();
632638
runtime.block_on(ServerInfo::new(ServerStats::default(), storage.as_deref()))?
633639
}
@@ -763,7 +769,9 @@ pub fn run_command(cmd: Command) -> Result<i32> {
763769
use crate::compiler;
764770

765771
trace!("Command::PackageToolchain({})", executable.display());
766-
let runtime = Runtime::new()?;
772+
let runtime = tokio::runtime::Builder::new_current_thread()
773+
.enable_all()
774+
.build()?;
767775
let jobserver = Client::new();
768776
let creator = ProcessCommandCreator::new(&jobserver);
769777
let args: Vec<_> = env::args_os().collect();
@@ -807,7 +815,9 @@ pub fn run_command(cmd: Command) -> Result<i32> {
807815

808816
let jobserver = Client::new();
809817
let conn = connect_or_start_server(&get_addr(), startup_timeout)?;
810-
let mut runtime = Runtime::new()?;
818+
let mut runtime = tokio::runtime::Builder::new_current_thread()
819+
.enable_all()
820+
.build()?;
811821
let res = do_compile(
812822
ProcessCommandCreator::new(&jobserver),
813823
&mut runtime,

0 commit comments

Comments
 (0)