Skip to content

Commit e1aea58

Browse files
committed
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 a888c16 commit e1aea58

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
@@ -624,7 +628,9 @@ pub fn run_command(cmd: Command) -> Result<i32> {
624628
// If there is no server, spawning a new server would start with zero stats
625629
// anyways, so we can just return (mostly) empty stats directly.
626630
Err(_) => {
627-
let runtime = Runtime::new()?;
631+
let runtime = tokio::runtime::Builder::new_current_thread()
632+
.enable_all()
633+
.build()?;
628634
let storage = storage_from_config(config, runtime.handle()).ok();
629635
runtime.block_on(ServerInfo::new(ServerStats::default(), storage.as_deref()))?
630636
}
@@ -760,7 +766,9 @@ pub fn run_command(cmd: Command) -> Result<i32> {
760766
use crate::compiler;
761767

762768
trace!("Command::PackageToolchain({})", executable.display());
763-
let runtime = Runtime::new()?;
769+
let runtime = tokio::runtime::Builder::new_current_thread()
770+
.enable_all()
771+
.build()?;
764772
let jobserver = Client::new();
765773
let creator = ProcessCommandCreator::new(&jobserver);
766774
let args: Vec<_> = env::args_os().collect();
@@ -804,7 +812,9 @@ pub fn run_command(cmd: Command) -> Result<i32> {
804812

805813
let jobserver = Client::new();
806814
let conn = connect_or_start_server(&get_addr(), startup_timeout)?;
807-
let mut runtime = Runtime::new()?;
815+
let mut runtime = tokio::runtime::Builder::new_current_thread()
816+
.enable_all()
817+
.build()?;
808818
let res = do_compile(
809819
ProcessCommandCreator::new(&jobserver),
810820
&mut runtime,

0 commit comments

Comments
 (0)