use arc_swap::ArcSwap;
use ferryman_edge_core::{build_table, ConfigToml, RouteTable, SharedTable};
use std::path::{Path, PathBuf};
use std::sync::Arc;
pub fn spawn_reload(path: PathBuf, table: SharedTable) {
tokio::spawn(async move {
let mut sig =
match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::user_defined1()) {
Ok(s) => s,
Err(e) => {
tracing::error!(?e, "failed to register SIGUSR1 for route reload");
return;
}
};
while sig.recv().await.is_some() {
match reload_once(&path) {
Ok(mut new_table) => {
new_table.inherit_breakers(&table.load());
table.store(Arc::new(new_table));
tracing::info!(path = %path.display(), "routing table reloaded");
}
Err(e) => {
tracing::error!(path = %path.display(), ?e, "route reload failed; keeping old table");
}
}
}
});
}
fn reload_once(path: &Path) -> anyhow::Result<RouteTable> {
let raw = std::fs::read_to_string(path)?;
let cfg: ConfigToml = toml::from_str(&raw)?;
build_table(&cfg)
}
#[allow(dead_code)]
pub fn new_shared(table: RouteTable) -> SharedTable {
Arc::new(ArcSwap::from_pointee(table))
}