Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable force shutdown with 2nd Ctrl+C #5414

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 37 additions & 14 deletions quickwit/quickwit-cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.

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;
Expand All @@ -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 {
Expand All @@ -53,6 +56,38 @@ pub struct RunCliCommand {
pub services: Option<HashSet<QuickwitService>>,
}

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<Self> {
let config_uri = matches
Expand Down Expand Up @@ -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,
Expand All @@ -129,6 +151,7 @@ impl RunCliCommand {
telemetry_handle.terminate_telemetry().await;
}
serve_result?;
info!("quickwit successfully terminated");
Ok(())
}
}
Expand Down
Loading