1 #![deny(unsafe_code)]
2 
3 //! Abstracting over accessing parts of stored value.
4 //!
5 //! Sometimes, there's a big globalish data structure (like a configuration for the whole program).
6 //! Then there are parts of the program that need access to up-to-date version of their *part* of
7 //! the configuration, but for reasons of code separation and reusability, it is not desirable to
8 //! pass the whole configuration to each of the parts.
9 //!
10 //! This module provides means to grant the parts access to the relevant subsets of such global
11 //! data structure while masking the fact it is part of the bigger whole from the component.
12 //!
13 //! Note that the [`cache`][crate::cache] module has its own [`Access`][crate::cache::Access] trait
14 //! that serves a similar purpose, but with cached access. The signatures are different, therefore
15 //! an incompatible trait.
16 //!
17 //! # The general idea
18 //!
19 //! Each part of the code accepts generic [`Access<T>`][Access] for the `T` of its interest. This
20 //! provides means to load current version of the structure behind the scenes and get only the
21 //! relevant part, without knowing what the big structure is.
22 //!
23 //! For technical reasons, the [`Access`] trait is not object safe. If type erasure is desired, it
24 //! is possible use the [`DynAccess`][crate::access::DynAccess] instead, which is object safe, but
25 //! slightly slower.
26 //!
27 //! For some cases, it is possible to use [`ArcSwapAny::map`]. If that is not flexible enough, the
28 //! [`Map`] type can be created directly.
29 //!
30 //! Note that the [`Access`] trait is also implemented for [`ArcSwapAny`] itself. Additionally,
31 //! there's the [`Constant`][crate::access::Constant] helper type, which is useful mostly for
32 //! testing (it doesn't allow reloading).
33 //!
34 //! # Performance
35 //!
36 //! In general, these utilities use [`ArcSwapAny::load`] internally and then apply the provided
37 //! transformation. This has several consequences:
38 //!
39 //! * Limitations of the [`load`][ArcSwapAny::load] apply ‒ including the recommendation to not
40 //!   hold the returned guard object for too long, but long enough to get consistency.
41 //! * The transformation should be cheap ‒ optimally just borrowing into the structure.
42 //!
43 //! # Examples
44 //!
45 //! ```rust
46 //! use std::sync::Arc;
47 //! use std::thread::{self, JoinHandle};
48 //! use std::time::Duration;
49 //!
50 //! use arc_swap::ArcSwap;
51 //! use arc_swap::access::{Access, Constant, Map};
52 //!
53 //! fn work_with_usize<A: Access<usize> + Send + 'static>(a: A) -> JoinHandle<()> {
54 //!     thread::spawn(move || {
55 //!         let mut value = 0;
56 //!         while value != 42 {
57 //!             let guard = a.load();
58 //!             value = *guard;
59 //!             println!("{}", value);
60 //!             // Not strictly necessary, but dropping the guard can free some resources, like
61 //!             // slots for tracking what values are still in use. We do it before the sleeping,
62 //!             // not at the end of the scope.
63 //!             drop(guard);
64 //!             thread::sleep(Duration::from_millis(50));
65 //!         }
66 //!     })
67 //! }
68 //!
69 //! // Passing the whole thing directly
70 //! // (If we kept another Arc to it, we could change the value behind the scenes)
71 //! work_with_usize(Arc::new(ArcSwap::from_pointee(42))).join().unwrap();
72 //!
73 //! // Passing a subset of a structure
74 //! struct Cfg {
75 //!     value: usize,
76 //! }
77 //!
78 //! let cfg = Arc::new(ArcSwap::from_pointee(Cfg { value: 0 }));
79 //! let thread = work_with_usize(Map::new(Arc::clone(&cfg), |cfg: &Cfg| &cfg.value));
80 //! cfg.store(Arc::new(Cfg { value: 42 }));
81 //! thread.join().unwrap();
82 //!
83 //! // Passing a constant that can't change. Useful mostly for testing purposes.
84 //! work_with_usize(Constant(42)).join().unwrap();
85 //! ```
86 
87 use std::marker::PhantomData;
88 use std::ops::Deref;
89 use std::rc::Rc;
90 use std::sync::Arc;
91 
92 use super::ref_cnt::RefCnt;
93 use super::strategy::Strategy;
94 use super::{ArcSwapAny, Guard};
95 
96 /// Abstracts over ways code can get access to a value of type `T`.
97 ///
98 /// This is the trait that parts of code will use when accessing a subpart of the big data
99 /// structure. See the [module documentation](index.html) for details.
100 pub trait Access<T> {
101     /// A guard object containing the value and keeping it alive.
102     ///
103     /// For technical reasons, the library doesn't allow direct access into the stored value. A
104     /// temporary guard object must be loaded, that keeps the actual value alive for the time of
105     /// use.
106     type Guard: Deref<Target = T>;
107 
108     /// The loading method.
109     ///
110     /// This returns the guard that holds the actual value. Should be called anew each time a fresh
111     /// value is needed.
load(&self) -> Self::Guard112     fn load(&self) -> Self::Guard;
113 }
114 
115 impl<T, A: Access<T> + ?Sized, P: Deref<Target = A>> Access<T> for P {
116     type Guard = A::Guard;
load(&self) -> Self::Guard117     fn load(&self) -> Self::Guard {
118         self.deref().load()
119     }
120 }
121 
122 impl<T> Access<T> for dyn DynAccess<T> + '_ {
123     type Guard = DynGuard<T>;
124 
load(&self) -> Self::Guard125     fn load(&self) -> Self::Guard {
126         self.load()
127     }
128 }
129 
130 impl<T> Access<T> for dyn DynAccess<T> + '_ + Send {
131     type Guard = DynGuard<T>;
132 
load(&self) -> Self::Guard133     fn load(&self) -> Self::Guard {
134         self.load()
135     }
136 }
137 
138 impl<T> Access<T> for dyn DynAccess<T> + '_ + Sync + Send {
139     type Guard = DynGuard<T>;
140 
load(&self) -> Self::Guard141     fn load(&self) -> Self::Guard {
142         self.load()
143     }
144 }
145 
146 impl<T: RefCnt, S: Strategy<T>> Access<T> for ArcSwapAny<T, S> {
147     type Guard = Guard<T, S>;
148 
load(&self) -> Self::Guard149     fn load(&self) -> Self::Guard {
150         self.load()
151     }
152 }
153 
154 #[derive(Debug)]
155 #[doc(hidden)]
156 pub struct DirectDeref<T: RefCnt, S: Strategy<T>>(Guard<T, S>);
157 
158 impl<T, S: Strategy<Arc<T>>> Deref for DirectDeref<Arc<T>, S> {
159     type Target = T;
deref(&self) -> &T160     fn deref(&self) -> &T {
161         self.0.deref().deref()
162     }
163 }
164 
165 impl<T, S: Strategy<Arc<T>>> Access<T> for ArcSwapAny<Arc<T>, S> {
166     type Guard = DirectDeref<Arc<T>, S>;
load(&self) -> Self::Guard167     fn load(&self) -> Self::Guard {
168         DirectDeref(self.load())
169     }
170 }
171 
172 impl<T, S: Strategy<Rc<T>>> Deref for DirectDeref<Rc<T>, S> {
173     type Target = T;
deref(&self) -> &T174     fn deref(&self) -> &T {
175         self.0.deref().deref()
176     }
177 }
178 
179 impl<T, S: Strategy<Rc<T>>> Access<T> for ArcSwapAny<Rc<T>, S> {
180     type Guard = DirectDeref<Rc<T>, S>;
load(&self) -> Self::Guard181     fn load(&self) -> Self::Guard {
182         DirectDeref(self.load())
183     }
184 }
185 
186 #[doc(hidden)]
187 pub struct DynGuard<T: ?Sized>(Box<dyn Deref<Target = T>>);
188 
189 impl<T: ?Sized> Deref for DynGuard<T> {
190     type Target = T;
deref(&self) -> &T191     fn deref(&self) -> &T {
192         &self.0
193     }
194 }
195 
196 /// An object-safe version of the [`Access`] trait.
197 ///
198 /// This can be used instead of the [`Access`] trait in case a type erasure is desired. This has
199 /// the effect of performance hit (due to boxing of the result and due to dynamic dispatch), but
200 /// makes certain code simpler and possibly makes the executable smaller.
201 ///
202 /// This is automatically implemented for everything that implements [`Access`].
203 ///
204 /// # Examples
205 ///
206 /// ```rust
207 /// use arc_swap::access::{Constant, DynAccess};
208 ///
209 /// fn do_something(value: Box<dyn DynAccess<usize> + Send>) {
210 ///     let v = value.load();
211 ///     println!("{}", *v);
212 /// }
213 ///
214 /// do_something(Box::new(Constant(42)));
215 /// ```
216 pub trait DynAccess<T> {
217     /// The equivalent of [`Access::load`].
load(&self) -> DynGuard<T>218     fn load(&self) -> DynGuard<T>;
219 }
220 
221 impl<T, A> DynAccess<T> for A
222 where
223     A: Access<T>,
224     A::Guard: 'static,
225 {
load(&self) -> DynGuard<T>226     fn load(&self) -> DynGuard<T> {
227         DynGuard(Box::new(Access::load(self)))
228     }
229 }
230 
231 /// [DynAccess] to [Access] wrapper.
232 ///
233 /// In previous versions, `Box<dyn DynAccess>` didn't implement [Access], to use inside [Map] one
234 /// could use this wrapper. Since then, a way was found to solve it. In most cases, this wrapper is
235 /// no longer necessary.
236 ///
237 /// This is left in place for two reasons:
238 /// * Backwards compatibility.
239 /// * Corner-cases not covered by the found solution. For example, trait inheritance in the form of
240 ///   `Box<dyn SomeTrait>` where `SomeTrait: Access` doesn't work out of the box and still needs
241 ///   this wrapper.
242 ///
243 /// # Examples
244 ///
245 /// The example is for the simple case (which is no longer needed, but may help as an inspiration).
246 ///
247 /// ```rust
248 /// use std::sync::Arc;
249 ///
250 /// use arc_swap::ArcSwap;
251 /// use arc_swap::access::{AccessConvert, DynAccess, Map};
252 ///
253 /// struct Inner {
254 ///     val: usize,
255 /// }
256 ///
257 /// struct Middle {
258 ///     inner: Inner,
259 /// }
260 ///
261 /// struct Outer {
262 ///     middle: Middle,
263 /// }
264 ///
265 /// let outer = Arc::new(ArcSwap::from_pointee(Outer {
266 ///     middle: Middle {
267 ///         inner: Inner {
268 ///             val: 42,
269 ///         }
270 ///     }
271 /// }));
272 ///
273 /// let middle: Arc<dyn DynAccess<Middle>> =
274 ///     Arc::new(Map::new(outer, |outer: &Outer| &outer.middle));
275 /// let inner: Arc<dyn DynAccess<Inner>> =
276 ///     Arc::new(Map::new(AccessConvert(middle), |middle: &Middle| &middle.inner));
277 /// let guard = inner.load();
278 /// assert_eq!(42, guard.val);
279 /// ```
280 pub struct AccessConvert<D>(pub D);
281 
282 impl<T, D> Access<T> for AccessConvert<D>
283 where
284     D: Deref,
285     D::Target: DynAccess<T>,
286 {
287     type Guard = DynGuard<T>;
288 
load(&self) -> Self::Guard289     fn load(&self) -> Self::Guard {
290         self.0.load()
291     }
292 }
293 
294 #[doc(hidden)]
295 #[derive(Copy, Clone, Debug)]
296 pub struct MapGuard<G, F, T, R> {
297     guard: G,
298     projection: F,
299     _t: PhantomData<fn(&T) -> &R>,
300 }
301 
302 impl<G, F, T, R> Deref for MapGuard<G, F, T, R>
303 where
304     G: Deref<Target = T>,
305     F: Fn(&T) -> &R,
306 {
307     type Target = R;
deref(&self) -> &R308     fn deref(&self) -> &R {
309         (self.projection)(&self.guard)
310     }
311 }
312 
313 /// An adaptor to provide access to a part of larger structure.
314 ///
315 /// This is the *active* part of this module. Use the [module documentation](index.html) for the
316 /// details.
317 #[derive(Copy, Clone, Debug)]
318 pub struct Map<A, T, F> {
319     access: A,
320     projection: F,
321     _t: PhantomData<fn() -> T>,
322 }
323 
324 impl<A, T, F> Map<A, T, F> {
325     /// Creates a new instance.
326     ///
327     /// # Parameters
328     ///
329     /// * `access`: Access to the bigger structure. This is usually something like `Arc<ArcSwap>`
330     ///   or `&ArcSwap`. It is technically possible to use any other [`Access`] here, though, for
331     ///   example to sub-delegate into even smaller structure from a [`Map`] (or generic
332     ///   [`Access`]).
333     /// * `projection`: A function (or closure) responsible to providing a reference into the
334     ///   bigger bigger structure, selecting just subset of it. In general, it is expected to be
335     ///   *cheap* (like only taking reference).
new<R>(access: A, projection: F) -> Self where F: Fn(&T) -> &R + Clone,336     pub fn new<R>(access: A, projection: F) -> Self
337     where
338         F: Fn(&T) -> &R + Clone,
339     {
340         Map {
341             access,
342             projection,
343             _t: PhantomData,
344         }
345     }
346 }
347 
348 impl<A, F, T, R> Access<R> for Map<A, T, F>
349 where
350     A: Access<T>,
351     F: Fn(&T) -> &R + Clone,
352 {
353     type Guard = MapGuard<A::Guard, F, T, R>;
load(&self) -> Self::Guard354     fn load(&self) -> Self::Guard {
355         let guard = self.access.load();
356         MapGuard {
357             guard,
358             projection: self.projection.clone(),
359             _t: PhantomData,
360         }
361     }
362 }
363 
364 #[doc(hidden)]
365 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
366 pub struct ConstantDeref<T>(T);
367 
368 impl<T> Deref for ConstantDeref<T> {
369     type Target = T;
deref(&self) -> &T370     fn deref(&self) -> &T {
371         &self.0
372     }
373 }
374 
375 /// Access to an constant.
376 ///
377 /// This wraps a constant value to provide [`Access`] to it. It is constant in the sense that,
378 /// unlike [`ArcSwapAny`] and [`Map`], the loaded value will always stay the same (there's no
379 /// remote `store`).
380 ///
381 /// The purpose is mostly testing and plugging a parameter that works generically from code that
382 /// doesn't need the updating functionality.
383 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
384 pub struct Constant<T>(pub T);
385 
386 impl<T: Clone> Access<T> for Constant<T> {
387     type Guard = ConstantDeref<T>;
load(&self) -> Self::Guard388     fn load(&self) -> Self::Guard {
389         ConstantDeref(self.0.clone())
390     }
391 }
392 
393 #[cfg(test)]
394 mod tests {
395     use super::super::{ArcSwap, ArcSwapOption};
396 
397     use super::*;
398 
check_static_dispatch_direct<A: Access<usize>>(a: A)399     fn check_static_dispatch_direct<A: Access<usize>>(a: A) {
400         assert_eq!(42, *a.load());
401     }
402 
check_static_dispatch<A: Access<Arc<usize>>>(a: A)403     fn check_static_dispatch<A: Access<Arc<usize>>>(a: A) {
404         assert_eq!(42, **a.load());
405     }
406 
407     /// Tests dispatching statically from arc-swap works
408     #[test]
static_dispatch()409     fn static_dispatch() {
410         let a = ArcSwap::from_pointee(42);
411         check_static_dispatch_direct(&a);
412         check_static_dispatch(&a);
413         check_static_dispatch(a);
414     }
415 
check_dyn_dispatch_direct(a: &dyn DynAccess<usize>)416     fn check_dyn_dispatch_direct(a: &dyn DynAccess<usize>) {
417         assert_eq!(42, *a.load());
418     }
419 
check_dyn_dispatch(a: &dyn DynAccess<Arc<usize>>)420     fn check_dyn_dispatch(a: &dyn DynAccess<Arc<usize>>) {
421         assert_eq!(42, **a.load());
422     }
423 
424     /// Tests we can also do a dynamic dispatch of the companion trait
425     #[test]
dyn_dispatch()426     fn dyn_dispatch() {
427         let a = ArcSwap::from_pointee(42);
428         check_dyn_dispatch_direct(&a);
429         check_dyn_dispatch(&a);
430     }
431 
check_transition<A>(a: A) where A: Access<usize>, A::Guard: 'static,432     fn check_transition<A>(a: A)
433     where
434         A: Access<usize>,
435         A::Guard: 'static,
436     {
437         check_dyn_dispatch_direct(&a)
438     }
439 
440     /// Tests we can easily transition from the static dispatch trait to the dynamic one
441     #[test]
transition()442     fn transition() {
443         let a = ArcSwap::from_pointee(42);
444         check_transition(&a);
445         check_transition(a);
446     }
447 
448     /// Test we can dispatch from Arc<ArcSwap<_>> or similar.
449     #[test]
indirect()450     fn indirect() {
451         let a = Arc::new(ArcSwap::from_pointee(42));
452         check_static_dispatch(&a);
453         check_dyn_dispatch(&a);
454     }
455 
456     struct Cfg {
457         value: usize,
458     }
459 
460     #[test]
map()461     fn map() {
462         let a = ArcSwap::from_pointee(Cfg { value: 42 });
463         let map = a.map(|a: &Cfg| &a.value);
464         check_static_dispatch_direct(&map);
465         check_dyn_dispatch_direct(&map);
466     }
467 
468     #[test]
map_option_some()469     fn map_option_some() {
470         let a = ArcSwapOption::from_pointee(Cfg { value: 42 });
471         let map = a.map(|a: &Option<Arc<Cfg>>| a.as_ref().map(|c| &c.value).unwrap());
472         check_static_dispatch_direct(&map);
473         check_dyn_dispatch_direct(&map);
474     }
475 
476     #[test]
map_option_none()477     fn map_option_none() {
478         let a = ArcSwapOption::empty();
479         let map = a.map(|a: &Option<Arc<Cfg>>| a.as_ref().map(|c| &c.value).unwrap_or(&42));
480         check_static_dispatch_direct(&map);
481         check_dyn_dispatch_direct(&map);
482     }
483 
484     #[test]
constant()485     fn constant() {
486         let c = Constant(42);
487         check_static_dispatch_direct(c);
488         check_dyn_dispatch_direct(&c);
489         check_static_dispatch_direct(c);
490     }
491 
492     #[test]
map_reload()493     fn map_reload() {
494         let a = ArcSwap::from_pointee(Cfg { value: 0 });
495         let map = a.map(|cfg: &Cfg| &cfg.value);
496         assert_eq!(0, *Access::load(&map));
497         a.store(Arc::new(Cfg { value: 42 }));
498         assert_eq!(42, *Access::load(&map));
499     }
500 
501     // Compile tests for dynamic access
_expect_access<T>(_: impl Access<T>)502     fn _expect_access<T>(_: impl Access<T>) {}
503 
_dyn_access<T>(x: Box<dyn DynAccess<T> + '_>)504     fn _dyn_access<T>(x: Box<dyn DynAccess<T> + '_>) {
505         _expect_access(x)
506     }
507 
_dyn_access_send<T>(x: Box<dyn DynAccess<T> + '_ + Send>)508     fn _dyn_access_send<T>(x: Box<dyn DynAccess<T> + '_ + Send>) {
509         _expect_access(x)
510     }
511 
_dyn_access_send_sync<T>(x: Box<dyn DynAccess<T> + '_ + Send + Sync>)512     fn _dyn_access_send_sync<T>(x: Box<dyn DynAccess<T> + '_ + Send + Sync>) {
513         _expect_access(x)
514     }
515 
516     #[test]
double_dyn_access_complex()517     fn double_dyn_access_complex() {
518         struct Inner {
519             val: usize,
520         }
521 
522         struct Middle {
523             inner: Inner,
524         }
525 
526         struct Outer {
527             middle: Middle,
528         }
529 
530         let outer = Arc::new(ArcSwap::from_pointee(Outer {
531             middle: Middle {
532                 inner: Inner { val: 42 },
533             },
534         }));
535 
536         let middle: Arc<dyn DynAccess<Middle>> =
537             Arc::new(Map::new(outer, |outer: &Outer| &outer.middle));
538         let inner: Arc<dyn DynAccess<Inner>> =
539             Arc::new(Map::new(middle, |middle: &Middle| &middle.inner));
540         // Damn. We have the DynAccess wrapper in scope and need to disambiguate the inner.load()
541         let guard = Access::load(&inner);
542         assert_eq!(42, guard.val);
543     }
544 }
545