tide_disco/
healthcheck.rs

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