Skip to content

Commit

Permalink
feat(error code when shutdown fails): set exit flag to 1 when shutdow…
Browse files Browse the repository at this point in the history
…n times out (#17676)

<!--
**Your PR title must conform to the conventional commit spec!**

  <type>(<scope>)!: <description>

  * `type` = chore, enhancement, feat, fix, docs
  * `!` = OPTIONAL: signals a breaking change
* `scope` = Optional when `type` is "chore" or "docs", available scopes
https://github.com/vectordotdev/vector/blob/master/.github/semantic.yml#L20
  * `description` = short description of the change

Examples:

  * enhancement(file source): Add `sort` option to sort discovered files
  * feat(new source): Initial `statsd` source
  * fix(file source): Fix a bug discovering new files
  * chore(external docs): Clarify `batch_size` option
-->

Issue: [Exit non-zero when Vector fails to gracefully
shutdown](#13731)

We use
[std::process::ExitCode](https://doc.rust-lang.org/stable/std/process/struct.ExitCode.html)
to provide the default platform-specific success and failure codes.
  • Loading branch information
DominicBurkart authored Jun 14, 2023
1 parent 83af7ea commit 53bfe0d
Showing 2 changed files with 17 additions and 10 deletions.
17 changes: 11 additions & 6 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#![allow(missing_docs)]
use std::{collections::HashMap, num::NonZeroUsize, path::PathBuf, time::Duration};
use std::{
collections::HashMap, num::NonZeroUsize, path::PathBuf, process::ExitCode as Exit,
time::Duration,
};

use exitcode::ExitCode;
use futures::StreamExt;
@@ -145,10 +148,10 @@ impl ApplicationConfig {
}

impl Application {
pub fn run() {
pub fn run() -> Exit {
let (runtime, app) = Self::prepare_start().unwrap_or_else(|code| std::process::exit(code));

runtime.block_on(app.run());
runtime.block_on(app.run())
}

pub fn prepare_start() -> Result<(Runtime, StartedApplication), ExitCode> {
@@ -242,7 +245,7 @@ pub struct StartedApplication {
}

impl StartedApplication {
pub async fn run(self) {
pub async fn run(self) -> Exit {
self.main().await.shutdown().await
}

@@ -317,7 +320,7 @@ pub struct FinishedApplication {
}

impl FinishedApplication {
pub async fn shutdown(self) {
pub async fn shutdown(self) -> Exit {
let FinishedApplication {
signal,
mut signal_rx,
@@ -335,18 +338,20 @@ impl FinishedApplication {
SignalTo::Shutdown => {
emit!(VectorStopped);
tokio::select! {
_ = topology_controller.stop() => (), // Graceful shutdown finished
_ = topology_controller.stop() => Exit::SUCCESS, // Graceful shutdown finished
_ = signal_rx.recv() => {
// It is highly unlikely that this event will exit from topology.
emit!(VectorQuit);
// Dropping the shutdown future will immediately shut the server down
Exit::FAILURE
}
}
}
SignalTo::Quit => {
// It is highly unlikely that this event will exit from topology.
emit!(VectorQuit);
drop(topology_controller);
Exit::FAILURE
}
_ => unreachable!(),
}
10 changes: 6 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -3,8 +3,10 @@
extern crate vector;
use vector::app::Application;

use std::process::ExitCode;

#[cfg(unix)]
fn main() {
fn main() -> ExitCode {
#[cfg(feature = "allocation-tracing")]
{
use crate::vector::internal_telemetry::allocations::{
@@ -35,14 +37,14 @@ fn main() {
}
}

Application::run();
Application::run()
}

#[cfg(windows)]
pub fn main() {
pub fn main() -> ExitCode {
// We need to be able to run vector in User Interactive mode. We first try
// to run vector as a service. If we fail, we consider that we are in
// interactive mode and then fallback to console mode. See
// https://docs.microsoft.com/en-us/dotnet/api/system.environment.userinteractive?redirectedfrom=MSDN&view=netcore-3.1#System_Environment_UserInteractive
vector::vector_windows::run().unwrap_or_else(|_| Application::run());
vector::vector_windows::run().unwrap_or_else(|_| Application::run())
}

0 comments on commit 53bfe0d

Please sign in to comment.