diff --git a/quickwit/quickwit-cli/src/service.rs b/quickwit/quickwit-cli/src/service.rs
index 40693e9d4b5..7c6314c0d14 100644
--- a/quickwit/quickwit-cli/src/service.rs
+++ b/quickwit/quickwit-cli/src/service.rs
@@ -18,9 +18,11 @@
// along with this program. If not, see .
use std::collections::HashSet;
+use std::pin::pin;
use std::str::FromStr;
use clap::{arg, ArgAction, ArgMatches, Command};
+use colored::Colorize;
use futures::future::select;
use itertools::Itertools;
use quickwit_common::runtimes::RuntimesConfig;
@@ -33,6 +35,7 @@ use quickwit_telemetry::payload::{QuickwitFeature, QuickwitTelemetryInfo, Teleme
use tokio::signal;
use tracing::{debug, info};
+use crate::checklist::{BLUE_COLOR, RED_COLOR};
use crate::{config_cli_arg, get_resolvers, load_node_config, start_actor_runtimes};
pub fn build_run_command() -> Command {
@@ -53,6 +56,38 @@ pub struct RunCliCommand {
pub services: Option>,
}
+async fn listen_interrupt() {
+ async fn ctrl_c() {
+ signal::ctrl_c()
+ .await
+ .expect("registering a signal handler for SIGINT should not fail");
+ // carriage return to hide the ^C echo from the terminal
+ print!("\r");
+ }
+ ctrl_c().await;
+ println!(
+ "{} Graceful shutdown initiated. Waiting for ingested data to be indexed. This may take a \
+ few minutes. Press Ctrl+C again to force shutdown.",
+ "❢".color(BLUE_COLOR)
+ );
+ tokio::spawn(async {
+ ctrl_c().await;
+ println!(
+ "{} Quickwit was forcefully shut down. Some data might not have been indexed.",
+ "✘".color(RED_COLOR)
+ );
+ std::process::exit(1);
+ });
+}
+
+async fn listen_sigterm() {
+ signal::unix::signal(signal::unix::SignalKind::terminate())
+ .expect("registering a signal handler for SIGTERM should not fail")
+ .recv()
+ .await;
+ info!("SIGTERM received");
+}
+
impl RunCliCommand {
pub fn parse_cli_args(mut matches: ArgMatches) -> anyhow::Result {
let config_uri = matches
@@ -95,20 +130,7 @@ impl RunCliCommand {
let runtimes_config = RuntimesConfig::default();
start_actor_runtimes(runtimes_config, &node_config.enabled_services)?;
let shutdown_signal = Box::pin(async {
- select(
- Box::pin(async {
- signal::ctrl_c()
- .await
- .expect("registering a signal handler for SIGINT should not fail");
- }),
- Box::pin(async {
- signal::unix::signal(signal::unix::SignalKind::terminate())
- .expect("registering a signal handler for SIGTERM should not fail")
- .recv()
- .await;
- }),
- )
- .await;
+ select(pin!(listen_interrupt()), pin!(listen_sigterm())).await;
});
let serve_result = serve_quickwit(
node_config,
@@ -129,6 +151,7 @@ impl RunCliCommand {
telemetry_handle.terminate_telemetry().await;
}
serve_result?;
+ info!("quickwit successfully terminated");
Ok(())
}
}