use crate::Control;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ReloadOutcome {
Unchanged,
Reloaded { hash: String },
}
pub trait ReloadSource {
fn recv(&mut self) -> Option<()>;
}
pub fn serve_reloads(control: &Control, source: &mut dyn ReloadSource) {
while source.recv().is_some() {
match control.reload_from_disk() {
Ok(ReloadOutcome::Unchanged) => {
tracing::debug!("reload trigger: manifest unchanged, keeping current set");
}
Ok(ReloadOutcome::Reloaded { hash }) => {
tracing::info!(config_version = %hash, "reload: swapped to new manifest");
}
Err(err) => {
match crate::diagnose(&err) {
Some(d) => tracing::error!(
error = %err,
code = d.code,
suggestion = d.suggestion,
docs = d.docs,
"reload failed; keeping current set"
),
None => {
tracing::error!(error = %err, "reload failed; keeping current set")
}
}
}
}
}
}
#[cfg(unix)]
pub struct SignalReloadSource {
signals: signal_hook::iterator::Signals,
}
#[cfg(unix)]
impl SignalReloadSource {
pub fn sighup() -> std::io::Result<Self> {
let signals = signal_hook::iterator::Signals::new([signal_hook::consts::SIGHUP])?;
Ok(Self { signals })
}
}
#[cfg(unix)]
impl ReloadSource for SignalReloadSource {
fn recv(&mut self) -> Option<()> {
self.signals.forever().next().map(|_| ())
}
}