use std::path::{Path, PathBuf};
use std::time::Duration;
use dynamic_config::{dynamic_config, BlockingExecutor};
use serde::Deserialize;
const DIRECTORY: &str = "/tmp/dynamic-config-smol";
#[dynamic_config(
files = ["/tmp/dynamic-config-smol/config.json"],
key = "server",
env = "APP_",
watch,
async,
diff,
)]
#[derive(Debug, Deserialize)]
struct ServerConfig {
greeting: String,
workers: usize,
}
struct Smol;
impl BlockingExecutor for Smol {
fn execute(&self, work: Box<dyn FnOnce() + Send + 'static>) {
smol::spawn(smol::unblock(work)).detach();
}
}
fn write(directory: &Path, greeting: &str, workers: usize) -> std::io::Result<()> {
std::fs::write(
directory.join("config.json"),
format!(r#"{{"server": {{"greeting": "{greeting}", "workers": {workers}}}}}"#),
)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let directory = PathBuf::from(DIRECTORY);
std::fs::create_dir_all(&directory)?;
write(&directory, "hello from smol", 4)?;
let _ = dynamic_config::set_blocking_executor(Smol);
smol::block_on(async {
ServerConfig::init_async().await?;
println!("loaded: {}", ServerConfig::current().greeting);
println!("workers: {}\n", ServerConfig::current().workers);
let handle = ServerConfig::start_watch()?;
let mut changes = ServerConfig::changes();
let editor = smol::spawn({
let directory = directory.clone();
async move {
for (greeting, workers) in [("edited once", 8), ("edited twice", 16)] {
smol::Timer::after(Duration::from_millis(400)).await;
let _ = write(&directory, greeting, workers);
}
}
});
for _ in 0..2 {
let config = changes.changed().await;
println!("woke up: {} ({} workers)", config.greeting, config.workers);
}
editor.await;
drop(handle);
Ok::<(), Box<dyn std::error::Error>>(())
})?;
let _ = std::fs::remove_dir_all(&directory);
Ok(())
}