feat(cli): add CliRunnerConfig for configurable graceful shutdown timeout (#20899)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matthias Seitz
2026-01-09 22:52:03 +01:00
committed by GitHub
parent e86c5fba53
commit 746baed2b1

View File

@@ -18,8 +18,8 @@ use tracing::{debug, error, trace};
///
/// Provides utilities for running a cli command to completion.
#[derive(Debug)]
#[non_exhaustive]
pub struct CliRunner {
config: CliRunnerConfig,
tokio_runtime: tokio::runtime::Runtime,
}
@@ -29,12 +29,18 @@ impl CliRunner {
///
/// The default tokio runtime is multi-threaded, with both I/O and time drivers enabled.
pub fn try_default_runtime() -> Result<Self, std::io::Error> {
Ok(Self { tokio_runtime: tokio_runtime()? })
Ok(Self { config: CliRunnerConfig::default(), tokio_runtime: tokio_runtime()? })
}
/// Create a new [`CliRunner`] from a provided tokio [`Runtime`](tokio::runtime::Runtime).
pub const fn from_runtime(tokio_runtime: tokio::runtime::Runtime) -> Self {
Self { tokio_runtime }
Self { config: CliRunnerConfig::new(), tokio_runtime }
}
/// Sets the [`CliRunnerConfig`] for this runner.
pub const fn with_config(mut self, config: CliRunnerConfig) -> Self {
self.config = config;
self
}
/// Executes an async block on the runtime and blocks until completion.
@@ -74,7 +80,7 @@ impl CliRunner {
// after the command has finished or exit signal was received we shutdown the task
// manager which fires the shutdown signal to all tasks spawned via the task
// executor and awaiting on tasks spawned with graceful shutdown
task_manager.graceful_shutdown_with_timeout(Duration::from_secs(5));
task_manager.graceful_shutdown_with_timeout(self.config.graceful_shutdown_timeout);
}
// `drop(tokio_runtime)` would block the current thread until its pools
@@ -128,7 +134,7 @@ impl CliRunner {
error!(target: "reth::cli", "shutting down due to error");
} else {
debug!(target: "reth::cli", "shutting down gracefully");
task_manager.graceful_shutdown_with_timeout(Duration::from_secs(5));
task_manager.graceful_shutdown_with_timeout(self.config.graceful_shutdown_timeout);
}
// Shutdown the runtime on a separate thread
@@ -211,6 +217,38 @@ pub struct CliContext {
pub task_executor: TaskExecutor,
}
/// Default timeout for graceful shutdown of tasks.
const DEFAULT_GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
/// Configuration for [`CliRunner`].
#[derive(Debug, Clone)]
pub struct CliRunnerConfig {
/// Timeout for graceful shutdown of tasks.
///
/// After the command completes, this is the maximum time to wait for spawned tasks
/// to finish before forcefully terminating them.
pub graceful_shutdown_timeout: Duration,
}
impl Default for CliRunnerConfig {
fn default() -> Self {
Self::new()
}
}
impl CliRunnerConfig {
/// Creates a new config with default values.
pub const fn new() -> Self {
Self { graceful_shutdown_timeout: DEFAULT_GRACEFUL_SHUTDOWN_TIMEOUT }
}
/// Sets the graceful shutdown timeout.
pub const fn with_graceful_shutdown_timeout(mut self, timeout: Duration) -> Self {
self.graceful_shutdown_timeout = timeout;
self
}
}
/// Creates a new default tokio multi-thread [Runtime](tokio::runtime::Runtime) with all features
/// enabled
pub fn tokio_runtime() -> Result<tokio::runtime::Runtime, std::io::Error> {