Available on crate features
config-reload and config only.Expand description
Universal configuration reloader for DFE components.
ConfigReloader<T> provides three reload triggers, any combination of
which can be enabled simultaneously:
- SIGHUP (Unix only) – standard daemon reload signal
- Periodic timer – reload every N seconds
- File polling – detect config file changes via mtime comparison
The reloader calls a user-supplied reload_fn to load config and a
validate_fn to validate before applying. On success it updates the
SharedConfig<T> which notifies all subscribers.
§Usage
use std::path::PathBuf;
use std::time::Duration;
use hyperi_rustlib::config::reloader::{ConfigReloader, ReloaderConfig};
use hyperi_rustlib::config::shared::SharedConfig;
#[derive(Clone, Debug, Default)]
struct AppConfig {
pub workers: usize,
}
#[tokio::main]
async fn main() {
let config = AppConfig { workers: 4 };
let shared = SharedConfig::new(config);
let reloader_config = ReloaderConfig {
config_path: Some(PathBuf::from("config.yaml")),
poll_interval: Duration::from_secs(5),
periodic_interval: Duration::ZERO, // disabled
debounce: Duration::from_millis(500),
enable_sighup: true,
};
let reloader = ConfigReloader::new(
reloader_config,
shared.clone(),
|| {
// Your config loading logic here
Ok(AppConfig { workers: 8 })
},
|cfg| {
// Your validation logic here
if cfg.workers == 0 {
return Err("workers must be > 0".into());
}
Ok(())
},
);
let _handle = reloader.start();
// ... run your application ...
}§Migration from Component-Specific Implementations
§From dfe-loader’s ConfigWatcher (file polling)
// Before:
let watcher = ConfigWatcher::new(WatcherConfig {
config_path, poll_interval, debounce, enabled: true,
}, shared)?;
let _handle = watcher.start();
// After:
let reloader = ConfigReloader::new(
ReloaderConfig {
config_path: Some(config_path),
poll_interval,
debounce,
enable_sighup: true, // bonus: also reload on SIGHUP
periodic_interval: Duration::ZERO,
},
shared,
|| Config::load(path), // your reload function
|c| c.validate(), // your validate function
);
let _handle = reloader.start();§From dfe-receiver’s config_reload_task (SIGHUP + periodic)
// Before (inline in main.rs):
tokio::spawn(config_reload_task(state, reload_secs));
// After:
let reloader = ConfigReloader::new(
ReloaderConfig {
periodic_interval: Duration::from_secs(reload_secs),
enable_sighup: true,
config_path: None, // no file watching
..Default::default()
},
shared,
|| Config::load(path),
|c| c.validate(),
);
let _handle = reloader.start();§From dfe-archiver (not yet wired)
The archiver has SharedConfig and reload_config() ready but not
connected. Use ConfigReloader to complete the integration:
let reloader = ConfigReloader::new(
ReloaderConfig {
config_path: config.config_path.as_ref().map(PathBuf::from),
periodic_interval: Duration::from_secs(config.config_reload_secs),
enable_sighup: true,
..Default::default()
},
shared,
|| load_config(config_path),
|c| validate_config(c),
);
let _handle = reloader.start();Structs§
- Config
Reloader - Reloader
Config - Configuration for the reloader.