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, Default, Deserialize, Serialize, PartialEq, Eq)]
31#[serde(rename_all = "snake_case")]
32pub enum HealthStatus {
33 #[default]
34 Available,
35 Initializing,
36 Unavailabale,
37 TemporarilyUnavailable,
38 Unhealthy,
39 ShuttingDown,
40}
41
42impl HealthCheck for HealthStatus {
43 fn status(&self) -> StatusCode {
44 match self {
45 // Return healthy in normal states even if the state is not `Available`, so that load
46 // balances and health monitors don't kill the service while it is starting up or
47 // gracefully shutting down.
48 Self::Available | Self::Initializing | Self::ShuttingDown => StatusCode::OK,
49 _ => StatusCode::SERVICE_UNAVAILABLE,
50 }
51 }
52}