pub struct Group<K, V, S = RandomState> { /* private fields */ }Expand description
Group represents a class of work and forms a namespace in which units of work can be executed with duplicate suppression.
Implementations§
Source§impl<K, V> Group<K, V, RandomState>
impl<K, V> Group<K, V, RandomState>
Source§impl<K, V, S> Group<K, V, S>
impl<K, V, S> Group<K, V, S>
Sourcepub fn with_hasher(hasher: S) -> Self
pub fn with_hasher(hasher: S) -> Self
Creates a new Group with the given hasher.
Sourcepub async fn work<F>(&self, key: K, func: F) -> Vwhere
F: AsyncFnOnce() -> V,
pub async fn work<F>(&self, key: K, func: F) -> Vwhere
F: AsyncFnOnce() -> V,
Executes and returns the results of the given function, making sure that only one execution is in-flight for a given key at a time.
If a duplicate comes in, the duplicate caller waits for the original to complete and receives the same results.
If the computation is cancelled or panics, another caller waiting for the same key may retry it.
Once the function completes, the key, if not forgotten, is removed from the group,
allowing future calls with the same key to execute the function again.
§Examples
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::time::Duration;
use mea::singleflight::Group;
let group = Group::new();
let counter = Arc::new(AtomicUsize::new(0));
let c1 = counter.clone();
let fut1 = group.work("key", || async move {
c1.fetch_add(1, Ordering::SeqCst);
// simulate heavy work to avoid immediate completion
tokio::time::sleep(Duration::from_millis(100)).await;
"result"
});
let c2 = counter.clone();
let fut2 = group.work("key", || async move {
c2.fetch_add(1, Ordering::SeqCst);
// simulate heavy work to avoid immediate completion
tokio::time::sleep(Duration::from_millis(100)).await;
"result"
});
let (r1, r2) = tokio::join!(fut1, fut2);
assert_eq!(r1, "result");
assert_eq!(r2, "result");
assert_eq!(counter.load(Ordering::SeqCst), 1);Sourcepub async fn try_work<E, F>(&self, key: K, func: F) -> Result<V, E>where
F: AsyncFnOnce() -> Result<V, E>,
pub async fn try_work<E, F>(&self, key: K, func: F) -> Result<V, E>where
F: AsyncFnOnce() -> Result<V, E>,
Executes and returns the results of the given function, making sure that only one execution is in-flight for a given key at a time.
If a duplicate comes in, the duplicate caller waits for the original to complete and receives the same results.
If the computation returns an error, it is returned to that caller. After an error, cancellation, or panic, another caller may retry the computation.
Once the function completes successfully, the key, if not forgotten, is removed from
the group, allowing future calls with the same key to execute the function again.
§Examples
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::time::Duration;
use mea::singleflight::Group;
let group = Group::new();
let fut1 = group.try_work("key", || async move {
// simulate heavy work to avoid immediate completion
tokio::time::sleep(Duration::from_millis(100)).await;
Err::<_, &'static str>("fut1")
});
let fut2 = group.try_work("key", || async move {
// simulate heavy work to avoid immediate completion
tokio::time::sleep(Duration::from_millis(200)).await;
Ok::<_, &'static str>("fut2")
});
let (r1, r2) = tokio::join!(fut1, fut2);
assert_eq!(r1, Err("fut1"));
assert_eq!(r2, Ok("fut2"));