veecle_os_runtime/datastore/
initialized_reader.rs1use core::cell::Ref;
2use core::marker::PhantomData;
3
4use crate::datastore::{Storable, slot};
5
6#[derive(Debug)]
52pub struct InitializedReader<'a, T>
53where
54 T: Storable + 'static,
55{
56 waiter: slot::Waiter<'a, T>,
57
58 marker: PhantomData<fn(T)>,
59}
60
61impl<T> InitializedReader<'_, T>
62where
63 T: Storable + 'static,
64{
65 #[veecle_telemetry::instrument]
71 pub fn read<U>(&self, f: impl FnOnce(&T::DataType) -> U) -> U {
72 self.waiter.read(|value| {
73 let value = value
74 .as_ref()
75 .expect("initialized reader should only access initialized values");
76
77 veecle_telemetry::trace!("Slot read", value = format_args!("{value:?}"));
78 f(value)
79 })
80 }
81
82 pub fn read_cloned(&self) -> T::DataType
87 where
88 T::DataType: Clone,
89 {
90 self.read(|t| t.clone())
91 }
92
93 #[veecle_telemetry::instrument]
101 pub async fn wait_for_update(&mut self) -> &mut Self {
102 self.waiter.wait().await;
103 self.waiter.update_generation();
104 self
105 }
106}
107
108impl<'a, T> InitializedReader<'a, T>
109where
110 T: Storable + 'static,
111{
112 pub(crate) fn new(waiter: slot::Waiter<'a, T>) -> Self {
114 Self {
115 waiter,
116 marker: Default::default(),
117 }
118 }
119}
120
121impl<T> super::combined_readers::Sealed for InitializedReader<'_, T> where T: Storable {}
122
123impl<T> super::combined_readers::CombinableReader for InitializedReader<'_, T>
124where
125 T: Storable,
126{
127 type ToBeRead = T::DataType;
128
129 fn borrow(&self) -> Ref<'_, Self::ToBeRead> {
130 Ref::map(self.waiter.borrow(), |t| t.as_ref().unwrap())
131 }
132
133 async fn wait_for_update(&mut self) {
134 self.wait_for_update().await;
135 }
136}
137
138#[cfg(test)]
139#[cfg_attr(coverage_nightly, coverage(off))]
140mod tests {
141 use core::pin::pin;
142 use futures::FutureExt;
143
144 use crate::datastore::{Reader, Slot, Storable, Writer, generational};
145
146 #[test]
147 fn read() {
148 #[derive(Eq, PartialEq, Debug, Clone, Storable)]
149 #[storable(crate = crate)]
150 struct Sensor(u8);
151
152 let source = pin!(generational::Source::new());
153 let slot = pin!(Slot::<Sensor>::new());
154
155 let mut writer = Writer::new(source.as_ref().waiter(), slot.as_ref());
156 let reader = Reader::from_slot(slot.as_ref());
157
158 assert!(reader.wait_init().now_or_never().is_none());
159
160 source.as_ref().increment_generation();
161 writer.write(Sensor(5)).now_or_never().unwrap();
162
163 let reader = Reader::from_slot(slot.as_ref())
164 .wait_init()
165 .now_or_never()
166 .unwrap();
167
168 assert_eq!(reader.read(|x: &Sensor| x.clone()), Sensor(5));
169 assert_eq!(reader.read_cloned(), Sensor(5));
170 }
171
172 #[test]
173 fn wait_for_update() {
174 #[derive(Eq, PartialEq, Debug, Clone, Storable)]
175 #[storable(crate = crate)]
176 struct Sensor(u8);
177
178 let source = pin!(generational::Source::new());
179 let slot = pin!(Slot::<Sensor>::new());
180
181 let mut writer = Writer::new(source.as_ref().waiter(), slot.as_ref());
182 let reader = Reader::from_slot(slot.as_ref());
183
184 source.as_ref().increment_generation();
185 writer.write(Sensor(1)).now_or_never().unwrap();
186
187 let mut reader = reader.wait_init().now_or_never().unwrap();
188
189 assert!(reader.wait_for_update().now_or_never().is_some());
190 assert!(reader.wait_for_update().now_or_never().is_none());
191
192 source.as_ref().increment_generation();
193 writer.write(Sensor(1)).now_or_never().unwrap();
194
195 reader
196 .wait_for_update()
197 .now_or_never()
198 .unwrap()
199 .read(|x| assert_eq!(x, &Sensor(1)));
200 }
201
202 #[test]
203 fn wait_init_wait_for_update() {
204 #[derive(Eq, PartialEq, Debug, Clone, Storable)]
205 #[storable(crate = crate)]
206 struct Sensor(u8);
207
208 let source = pin!(generational::Source::new());
209 let slot = pin!(Slot::<Sensor>::new());
210
211 let mut writer = Writer::new(source.as_ref().waiter(), slot.as_ref());
212 let reader = Reader::from_slot(slot.as_ref());
213
214 let mut wait_init_fut = pin!(reader.wait_init());
215 assert!(wait_init_fut.as_mut().now_or_never().is_none());
216 source.as_ref().increment_generation();
218 writer.write(Sensor(1)).now_or_never().unwrap();
219
220 let mut reader = wait_init_fut.now_or_never().unwrap();
221
222 reader
224 .wait_for_update()
225 .now_or_never()
226 .unwrap()
227 .read(|x| assert_eq!(x, &Sensor(1)));
228 }
229}