1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
// Copyright (c) 2022 Espresso Systems (espressosys.com)
// This file is part of the tide-disco library.
// You should have received a copy of the MIT License
// along with the tide-disco library. If not, see <https://mit-license.org/>.
use crate::StatusCode;
use serde::{Deserialize, Serialize};
/// A response to a healthcheck endpoint.
///
/// A type implementing [HealthCheck] may be returned from a healthcheck endpoint itself (via its
/// [Serialize] implementation) as well as incorporated automatically into the global healthcheck
/// endpoint for an app. The global healthcheck will fail if any of the module healthchecks return
/// an implementation `h` of [HealthCheck] where `h.status() != StatusCode::OK`.
///
/// We provide a standard implementation [HealthStatus] which has variants for common states an
/// application might encounter. We recommend using this implementation as a standard, although it
/// is possible to implement the [HealthCheck] trait yourself if you desire more information in
/// your healthcheck response.
pub trait HealthCheck: Serialize {
/// The status of this health check.
///
/// Should return [StatusCode::OK] if the status is considered healthy, and some other status
/// code if it is not.
fn status(&self) -> StatusCode;
}
/// Common health statuses of an application.
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum HealthStatus {
Initializing,
Available,
Unavailabale,
TemporarilyUnavailable,
Unhealthy,
ShuttingDown,
}
impl Default for HealthStatus {
fn default() -> Self {
Self::Available
}
}
impl HealthCheck for HealthStatus {
fn status(&self) -> StatusCode {
match self {
// Return healthy in normal states even if the state is not `Available`, so that load
// balances and health monitors don't kill the service while it is starting up or
// gracefully shutting down.
Self::Available | Self::Initializing | Self::ShuttingDown => StatusCode::OK,
_ => StatusCode::SERVICE_UNAVAILABLE,
}
}
}