Skip to main content

shep_core/config/app/
probe.rs

1// use schemars::generate
2use crate::values::UpDuration;
3use serde::{Deserialize, Serialize};
4
5/// How a health probe checks a sheep
6// wire format: changing these strings is a breaking change
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
9#[serde(rename_all = "snake_case")]
10pub enum ProbeKind {
11    /// HTTP GET must return 2xx
12    Http,
13    /// TCP connect must succeed
14    Tcp,
15    /// Command must exit 0
16    Exec,
17}
18
19/// Readiness/liveness probe configuration (spec §7)
20// wire format: changing field names/defaults is a breaking change
21// `deny_unknown_fields` used to live here. This type rides the wire inside
22// `AppConfig` (itself carried by `Request::Start`, `Request::Add`, and
23// `Response::SheepConfig`), where an unknown field means a newer peer, not
24// a typo — denying it here would make a newer daemon's reply break an
25// older client. The denial moved to `Flockfile::parse`, where the input
26// really is a hand-written file. Do not restore the serde attribute here.
27//
28// The schema-only sibling attribute below is not the same thing and stays:
29// `schemars(deny_unknown_fields)` only shapes the generated
30// `additionalProperties: false`, which an editor uses to flag a Flockfile
31// typo before a parse ever runs. It never reaches `#[derive(Deserialize)]`
32// (schemars mirrors it into a synthesized attribute its own macro expansion
33// reads, not the real one), so the wire still tolerates an unknown field.
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
36#[cfg_attr(feature = "schema", schemars(deny_unknown_fields))]
37pub struct ProbeConfig {
38    /// Probe mechanism
39    pub kind: ProbeKind,
40    /// URL (http), `host:port` (tcp), or command line (exec)
41    pub target: String,
42    /// Time between probes (default 10s)
43    #[serde(default = "default_probe_interval")]
44    pub interval: UpDuration,
45    /// Per-probe timeout (default 5s)
46    #[serde(default = "default_probe_timeout")]
47    pub timeout: UpDuration,
48    /// Consecutive failures before the probe reports unhealthy (default 3)
49    #[serde(default = "default_failure_threshold")]
50    pub failure_threshold: u32,
51}
52
53pub(super) fn default_probe_interval() -> UpDuration {
54    UpDuration::from_millis(10_000)
55}
56
57pub(super) fn default_probe_timeout() -> UpDuration {
58    UpDuration::from_millis(5_000)
59}
60
61pub(super) fn default_failure_threshold() -> u32 {
62    3
63}