Concept
The rcu method is used for thread-safe updates that depend on the current value. It is essential when multiple threads might attempt to update the data simultaneously. If an update occurs while your closure is running, rcu will retry the closure with the new value.
Best Practice: Minimize work inside rcu
Because rcu may call your closure multiple times due to retries, you should perform expensive computations outside the rcu block. Only perform the cheap operations (like cloning the container and inserting the result) inside the closure.
Example
use std::collections::HashMap;
use std::sync::Arc;
use arc_swap::ArcSwap;
use once_cell::sync::Lazy;
type Cache = HashMap<usize, usize>;
static CACHE: Lazy<ArcSwap<Cache>> = Lazy::new(|| ArcSwap::default());
fn cached_computation(x: usize) -> usize {
let cache = CACHE.load();
if let Some(result) = cache.get(&x) { return *result; }
// Expensive work done OUTSIDE rcu
let result = x * 2;
CACHE.rcu(|cache| {
// Cheap work (cloning the map) done INSIDE rcu
let mut cache = HashMap::clone(cache);
cache.insert(x, result);
cache
});
result
}