Avoid hangs before exiting CLI (#4793)

## Summary

The resolver sometimes starts HTTP requests that end up not being
necessary. When dropping the Tokio runtime before exiting we currently
wait for those to complete. This can cause noticeable hangs in the CLI,
particularly when the runtime is blocked on slow DNS resolution.

Resolves https://github.com/astral-sh/uv/issues/4599.

## Test Plan

This change resolves any reproducible hangs for me locally.
This commit is contained in:
Ibraheem Ahmed 2024-07-03 20:05:44 -04:00 committed by GitHub
parent de40f798b9
commit 576ba9c522
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -951,12 +951,19 @@ fn main() -> ExitCode {
// https://learn.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations?view=msvc-170 // https://learn.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations?view=msvc-170
let stack_size = stack_size.parse().expect("Invalid stack size"); let stack_size = stack_size.parse().expect("Invalid stack size");
let tokio_main = move || { let tokio_main = move || {
tokio::runtime::Builder::new_multi_thread() let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all() .enable_all()
.thread_stack_size(stack_size) .thread_stack_size(stack_size)
.build() .build()
.expect("Failed building the Runtime") .expect("Failed building the Runtime");
.block_on(run()) let result = runtime.block_on(run());
// Avoid waiting for pending tasks to complete.
//
// The resolver may have kicked off HTTP requests during resolution that
// turned out to be unnecessary. Waiting for those to complete can cause
// the CLI to hang before exiting.
runtime.shutdown_background();
result
}; };
std::thread::Builder::new() std::thread::Builder::new()
.stack_size(stack_size) .stack_size(stack_size)
@ -965,11 +972,13 @@ fn main() -> ExitCode {
.join() .join()
.expect("Tokio executor failed, was there a panic?") .expect("Tokio executor failed, was there a panic?")
} else { } else {
tokio::runtime::Builder::new_multi_thread() let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all() .enable_all()
.build() .build()
.expect("Failed building the Runtime") .expect("Failed building the Runtime");
.block_on(run()) let result = runtime.block_on(run());
runtime.shutdown_background();
result
}; };
match result { match result {