kumo_server_common/
config_handle.rs1use arc_swap::{ArcSwap, Guard};
2use std::fmt::Debug;
3use std::sync::atomic::{AtomicUsize, Ordering};
4use std::sync::Arc;
5
6#[derive(Clone)]
15pub struct ConfigHandle<T: Clone + Send> {
16 inner: Arc<Inner<T>>,
17}
18
19struct Inner<T: Clone + Send> {
20 value: ArcSwap<T>,
21 generation: AtomicUsize,
22}
23
24impl<T: Clone + Send + Debug> Debug for ConfigHandle<T> {
25 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 fmt.debug_struct("ConfigHandle")
27 .field("value", &self.inner.value)
28 .field("generation", &self.inner.generation)
29 .finish()
30 }
31}
32
33impl<T: Clone + Send> ConfigHandle<T> {
34 pub fn new(value: T) -> Self {
35 Self {
36 inner: Arc::new(Inner {
37 value: ArcSwap::from_pointee(value),
38 generation: AtomicUsize::new(0),
39 }),
40 }
41 }
42
43 pub fn generation(&self) -> usize {
44 self.inner.generation.load(Ordering::SeqCst)
45 }
46
47 pub fn update(&self, new_value: T) -> usize {
50 self.inner.value.swap(Arc::new(new_value));
51
52 self.inner.generation.fetch_add(1, Ordering::SeqCst) + 1
53 }
54
55 pub fn borrow(&self) -> Guard<Arc<T>> {
58 self.inner.value.load()
59 }
60}