Skip to content

Commit 27ea304

Browse files
committed
wip
1 parent 5d45ddd commit 27ea304

1 file changed

Lines changed: 45 additions & 27 deletions

File tree

bin/ev-reth/src/main.rs

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,18 @@ struct NodeConfig {
6464
}
6565

6666
impl NodeConfig {
67+
/// Minimum allowed shutdown timeout in seconds
68+
const MIN_SHUTDOWN_TIMEOUT_SECS: u64 = 1;
69+
6770
/// Default shutdown timeout in seconds (optimized for containers)
6871
const DEFAULT_SHUTDOWN_TIMEOUT_SECS: u64 = 15;
6972

7073
/// Maximum allowed shutdown timeout in seconds (5 minutes)
7174
const MAX_SHUTDOWN_TIMEOUT_SECS: u64 = 300;
7275

76+
/// Minimum allowed status check interval in seconds
77+
const MIN_STATUS_CHECK_INTERVAL_SECS: u64 = 1;
78+
7379
/// Default status check interval in seconds (1 hour)
7480
const DEFAULT_STATUS_CHECK_INTERVAL_SECS: u64 = 3600;
7581

@@ -102,14 +108,14 @@ impl NodeConfig {
102108
fn parse_shutdown_timeout() -> Duration {
103109
match std::env::var("EV_RETH_SHUTDOWN_TIMEOUT") {
104110
Ok(val) => match val.parse::<u64>() {
105-
Ok(secs) if secs > 0 && secs <= Self::MAX_SHUTDOWN_TIMEOUT_SECS => {
111+
Ok(secs) if secs >= Self::MIN_SHUTDOWN_TIMEOUT_SECS && secs <= Self::MAX_SHUTDOWN_TIMEOUT_SECS => {
106112
tracing::info!("Using custom shutdown timeout of {}s from environment", secs);
107113
Duration::from_secs(secs)
108114
}
109115
Ok(secs) => {
110116
tracing::warn!(
111-
"Shutdown timeout {}s is out of bounds (1-{}), using default {}s",
112-
secs, Self::MAX_SHUTDOWN_TIMEOUT_SECS, Self::DEFAULT_SHUTDOWN_TIMEOUT_SECS
117+
"Shutdown timeout {}s is out of bounds ({}-{}), using default {}s",
118+
secs, Self::MIN_SHUTDOWN_TIMEOUT_SECS, Self::MAX_SHUTDOWN_TIMEOUT_SECS, Self::DEFAULT_SHUTDOWN_TIMEOUT_SECS
113119
);
114120
Duration::from_secs(Self::DEFAULT_SHUTDOWN_TIMEOUT_SECS)
115121
}
@@ -131,14 +137,14 @@ impl NodeConfig {
131137
fn parse_status_check_interval() -> u64 {
132138
match std::env::var("EV_RETH_STATUS_CHECK_INTERVAL") {
133139
Ok(val) => match val.parse::<u64>() {
134-
Ok(secs) if secs > 0 && secs <= Self::MAX_STATUS_CHECK_INTERVAL_SECS => {
140+
Ok(secs) if secs >= Self::MIN_STATUS_CHECK_INTERVAL_SECS && secs <= Self::MAX_STATUS_CHECK_INTERVAL_SECS => {
135141
tracing::info!("Using custom status check interval of {}s from environment", secs);
136142
secs
137143
}
138144
Ok(secs) => {
139145
tracing::warn!(
140-
"Status check interval {}s is out of bounds (1-{}), using default {}s",
141-
secs, Self::MAX_STATUS_CHECK_INTERVAL_SECS, Self::DEFAULT_STATUS_CHECK_INTERVAL_SECS
146+
"Status check interval {}s is out of bounds ({}-{}), using default {}s",
147+
secs, Self::MIN_STATUS_CHECK_INTERVAL_SECS, Self::MAX_STATUS_CHECK_INTERVAL_SECS, Self::DEFAULT_STATUS_CHECK_INTERVAL_SECS
142148
);
143149
Self::DEFAULT_STATUS_CHECK_INTERVAL_SECS
144150
}
@@ -177,35 +183,44 @@ async fn signal_fallback_mechanism(config: &NodeConfig) {
177183
std::future::pending::<()>().await;
178184
}
179185

180-
/// Handle shutdown signals with optimized signal handling
186+
/// Handle shutdown signals with optimized, non-redundant signal handling
181187
async fn handle_shutdown_signals() {
182188
#[cfg(unix)]
183189
{
184-
// On Unix systems, use a single select to handle both SIGTERM and SIGINT efficiently
185-
// This avoids redundant signal handling and potential race conditions
186-
match signal::unix::signal(signal::unix::SignalKind::terminate()) {
187-
Ok(mut sigterm) => {
190+
// On Unix systems, handle SIGTERM and SIGINT separately to avoid redundancy
191+
// SIGTERM is sent by process managers, SIGINT is sent by Ctrl+C
192+
match (
193+
signal::unix::signal(signal::unix::SignalKind::terminate()),
194+
signal::unix::signal(signal::unix::SignalKind::interrupt())
195+
) {
196+
(Ok(mut sigterm), Ok(mut sigint)) => {
188197
tokio::select! {
189198
_ = sigterm.recv() => {
190199
tracing::info!("Received SIGTERM, initiating graceful shutdown");
191200
}
192-
_ = signal::ctrl_c() => {
193-
tracing::info!("Received SIGINT/Ctrl+C, initiating graceful shutdown");
201+
_ = sigint.recv() => {
202+
tracing::info!("Received SIGINT, initiating graceful shutdown");
194203
}
195204
}
196205
}
197-
Err(err) => {
198-
tracing::warn!("Failed to install SIGTERM handler: {}, using SIGINT only", err);
199-
// Fallback to SIGINT only - this is the most common scenario
200-
if let Err(ctrl_c_err) = signal::ctrl_c().await {
201-
tracing::error!("Failed to wait for SIGINT: {}", ctrl_c_err);
202-
tracing::warn!("No signal handling available, shutdown will only occur on natural node exit");
203-
let config = NodeConfig::from_env();
204-
signal_fallback_mechanism(&config).await;
205-
} else {
206-
tracing::info!("Received SIGINT/Ctrl+C, initiating graceful shutdown");
206+
(Ok(mut sigterm), Err(sigint_err)) => {
207+
tracing::warn!("Failed to install SIGINT handler: {}, using SIGTERM only", sigint_err);
208+
if sigterm.recv().await.is_some() {
209+
tracing::info!("Received SIGTERM, initiating graceful shutdown");
207210
}
208211
}
212+
(Err(sigterm_err), Ok(mut sigint)) => {
213+
tracing::warn!("Failed to install SIGTERM handler: {}, using SIGINT only", sigterm_err);
214+
if sigint.recv().await.is_some() {
215+
tracing::info!("Received SIGINT, initiating graceful shutdown");
216+
}
217+
}
218+
(Err(sigterm_err), Err(sigint_err)) => {
219+
tracing::error!("Failed to install both SIGTERM and SIGINT handlers: SIGTERM={}, SIGINT={}", sigterm_err, sigint_err);
220+
tracing::warn!("No signal handling available, shutdown will only occur on natural node exit");
221+
let config = NodeConfig::from_env();
222+
signal_fallback_mechanism(&config).await;
223+
}
209224
}
210225
}
211226

@@ -371,14 +386,17 @@ fn main() {
371386
_ = handle_shutdown_signals() => {
372387
tracing::info!("Shutdown signal received, initiating graceful shutdown");
373388

374-
// Structured shutdown phases for better observability
375-
tracing::info!("Phase 1 - Stopping new connections");
376-
tracing::info!("Phase 2 - Draining active requests");
389+
// Structured shutdown phases for better observability (informational only)
390+
// Note: These phases are logged for monitoring purposes but don't implement
391+
// specific connection stopping or request draining - the underlying reth node
392+
// handles the actual shutdown logic when the handle is dropped
393+
tracing::info!("Phase 1 - Initiating shutdown sequence");
394+
tracing::info!("Phase 2 - Waiting for graceful node termination");
377395

378396
// Wait for the node to actually exit with a timeout
379397
let shutdown_result = timeout(config.shutdown_timeout, &mut handle.node_exit_future).await;
380398

381-
tracing::info!("Phase 3 - Shutdown completed");
399+
tracing::info!("Phase 3 - Shutdown sequence completed");
382400

383401
match shutdown_result {
384402
Ok(result) => {

0 commit comments

Comments
 (0)