use dynamic_config::{dynamic_config, Fetched, Format};
use embassy_executor::{Executor, Spawner};
use serde::Deserialize;
use static_cell::StaticCell;
#[dynamic_config(files = [], key = "server", env = "APP_", async)]
#[derive(Debug, Deserialize)]
struct ServerConfig {
greeting: String,
workers: usize,
}
#[embassy_executor::task]
async fn reader() {
let mut changes = ServerConfig::changes();
loop {
let config = changes.changed().await;
println!(
" reader woke: {} ({} workers)",
config.greeting, config.workers
);
}
}
#[embassy_executor::task]
async fn pusher() {
embassy_futures::yield_now().await;
println!("two pushes with no turn for the reader in between:");
push("first", 1);
push("second", 2);
embassy_futures::yield_now().await;
embassy_futures::yield_now().await;
println!("\n ...one wakeup, carrying the *latest* of them.");
println!(" Reloads that land while nothing is awaiting are not queued:");
println!(" waking to the newest configuration is what a reader wants, and");
println!(" a queue would hand it stale ones first.\n");
println!("and one more, with the reader waiting:");
push("third", 3);
embassy_futures::yield_now().await;
embassy_futures::yield_now().await;
println!("\nDriven by an executor with no threads, no reactor and no");
println!("allocation in its scheduler. `changes()` is a `Future` over a");
println!("generation counter and a list of wakers — `std`, and nothing else.");
std::process::exit(0);
}
fn push(greeting: &str, workers: usize) {
let document = format!(r#"{{"server": {{"greeting": "{greeting}", "workers": {workers}}}}}"#);
if let Err(error) = ServerConfig::apply_remote(Fetched::new(document, Format::Json)) {
println!(" the document did not apply: {error}");
}
}
#[embassy_executor::task]
async fn start(spawner: Spawner) {
spawner.spawn(reader().expect("the task pool has room"));
spawner.spawn(pusher().expect("the task pool has room"));
}
static EXECUTOR: StaticCell<Executor> = StaticCell::new();
fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| spawner.spawn(start(spawner).expect("the task pool has room")));
}