core_snapshot/
core_snapshot.rs1use std::sync::{Arc, Mutex, OnceLock};
14
15use dynamic_config_web_core::Sections;
16
17#[derive(Debug)]
18struct Server {
19 port: u16,
20 generation: u32,
21}
22
23#[derive(Debug)]
24struct Features {
25 cache: bool,
26 generation: u32,
27}
28
29fn state() -> &'static Mutex<(Arc<Server>, Arc<Features>)> {
31 static STATE: OnceLock<Mutex<(Arc<Server>, Arc<Features>)>> = OnceLock::new();
32
33 STATE.get_or_init(|| {
34 Mutex::new((
35 Arc::new(Server {
36 port: 8080,
37 generation: 1,
38 }),
39 Arc::new(Features {
40 cache: false,
41 generation: 1,
42 }),
43 ))
44 })
45}
46
47fn reload(generation: u32) {
48 let mut guard = state().lock().expect("not poisoned");
49
50 *guard = (
51 Arc::new(Server {
52 port: 8080 + u16::try_from(generation).unwrap_or(0),
53 generation,
54 }),
55 Arc::new(Features {
56 cache: generation.is_multiple_of(2),
57 generation,
58 }),
59 );
60}
61
62fn main() {
63 let sections = Sections::new()
64 .section(|| Some(state().lock().expect("not poisoned").0.clone()))
65 .section(|| Some(state().lock().expect("not poisoned").1.clone()));
66
67 println!("sections: {:?}\n", sections.names());
68
69 let snapshot = sections.take();
73
74 let server = snapshot.require::<Server>().expect("in scope");
75
76 reload(2); let features = snapshot.require::<Features>().expect("in scope");
79
80 println!("through one snapshot, across a reload:");
81 println!(
82 " server = port {}, generation {}",
83 server.port, server.generation
84 );
85 println!(
86 " features = cache {}, generation {} (same instant)\n",
87 features.cache, features.generation
88 );
89 assert_eq!(server.generation, features.generation);
90
91 let next = sections.take();
94
95 println!("the next snapshot:");
96 println!(
97 " features = {:?}\n",
98 next.require::<Features>().expect("in scope")
99 );
100
101 let missing = snapshot.require::<String>().unwrap_err();
103
104 println!("asking for an undeclared section:\n {missing}");
105}