Skip to main content

pharos_plugins/
reload.rs

1//! Reload Directive configuration.
2
3use std::time::Duration;
4
5use pharos_corefile::{Cursor, Error};
6
7#[derive(Clone, Copy, Debug)]
8pub struct Reload {
9    pub interval: Duration,
10    pub jitter: Duration,
11}
12
13/// Parse the timing options without starting a watcher.
14pub fn parse(cursor: &mut Cursor<'_>) -> Result<Reload, Error> {
15    cursor.next();
16    let args = cursor.remaining_args();
17    if args.len() > 2 {
18        return Err(cursor.arg_err());
19    }
20    let duration = |value: &str| {
21        if let Some(magnitude) = value.strip_prefix('-') {
22            if magnitude.starts_with(['-', '+']) {
23                return None;
24            }
25            let parsed = crate::health::parse_duration(magnitude)?;
26            return parsed.is_zero().then_some(parsed);
27        }
28        crate::health::parse_duration(value)
29    };
30    let interval = match args.first() {
31        Some(value) => duration(value).ok_or_else(|| cursor.error("invalid interval"))?,
32        None => Duration::from_secs(30),
33    };
34    if interval < Duration::from_secs(2) {
35        return Err(cursor.error("interval must be at least 2s"));
36    }
37    let jitter = match args.get(1) {
38        Some(value) => duration(value).ok_or_else(|| cursor.error("invalid jitter"))?,
39        None => Duration::from_secs(15),
40    };
41    if !jitter.is_zero() && jitter < Duration::from_secs(1) {
42        return Err(cursor.error("jitter must be zero or at least 1s"));
43    }
44    Ok(Reload {
45        interval,
46        jitter: jitter.min(interval / 2),
47    })
48}