pub struct Handle<T, V = T> { /* private fields */ }Expand description
A clonable handle that can be used to remotely execute a closure on the corresponding [Actor].
Handles are the primary way to interact with actors. Clone them freely to share
access across tasks. For read-only access, see ReadHandle. For local
synchronization, see Cache. For rate-limited updates, see Throttle.
The second type parameter V is the broadcast type. By default V = T,
meaning the actor broadcasts clones of itself. To broadcast a different
type, implement BroadcastAs<V> and specify V explicitly
(e.g. Handle::<MyType, Summary>::new(val)).
Implementations§
Source§impl<T, V> Handle<T, V>
impl<T, V> Handle<T, V>
Sourcepub fn new(val: T) -> Handle<T, V>
pub fn new(val: T) -> Handle<T, V>
Creates a new Handle and spawns the corresponding [Actor].
For Clone types, V defaults to T — the actor broadcasts clones of
itself and you can simply write Handle::new(val).
For non-Clone types (or to broadcast a lightweight summary), implement
BroadcastAs<V> and specify V explicitly:
#[derive(Clone, Debug, PartialEq)]
struct Size(usize);
impl BroadcastAs<Size> for Vec<u8> {
fn to_broadcast(&self) -> Size { Size(self.len()) }
}
let handle: Handle<Vec<u8>, Size> = Handle::new(vec![1, 2, 3]);
let mut rx = handle.subscribe();Sourcepub fn new_throttled<C, F>(
val: T,
client: C,
call: fn(&C, F),
freq: Frequency,
) -> Handle<T, V>
pub fn new_throttled<C, F>( val: T, client: C, call: fn(&C, F), freq: Frequency, ) -> Handle<T, V>
Creates a new Handle and initializes a corresponding Throttle.
The throttle fires given a specified Frequency.
See Handle::spawn_throttle for an example.
Source§impl<T, V> Handle<T, V>
impl<T, V> Handle<T, V>
Sourcepub fn subscribe(&self) -> Receiver<V>
pub fn subscribe(&self) -> Receiver<V>
Returns a tokio::sync::broadcast::Receiver that receives all broadcasted values.
Note that the inner value might not actually have changed.
It broadcasts on any method that has a mutable reference to the actor.
§Examples
let handle = Handle::new(None);
let mut rx = handle.subscribe();
handle.set(Some("testing!")).await;
assert_eq!(rx.recv().await.unwrap(), Some("testing!"));Sourcepub fn get_read_handle(&self) -> ReadHandle<T, V>
pub fn get_read_handle(&self) -> ReadHandle<T, V>
Returns a ReadHandle that provides read-only access to this actor.
Source§impl<T: Send + Sync + 'static, V> Handle<T, V>
impl<T: Send + Sync + 'static, V> Handle<T, V>
Sourcepub async fn set(&self, val: T)
pub async fn set(&self, val: T)
Overwrites the inner value of the actor with the new value. Broadcasts the new value to all subscribers.
§Examples
let handle = Handle::new(None);
handle.set(Some(1)).await;
assert_eq!(handle.get().await, Some(1));Sourcepub async fn set_if_changed(&self, val: T)where
T: PartialEq,
pub async fn set_if_changed(&self, val: T)where
T: PartialEq,
Overwrites the inner value, but only broadcasts if it actually changed.
§Examples
let handle = Handle::new(1);
let mut rx = handle.subscribe();
handle.set_if_changed(1).await; // Same value, no broadcast
handle.set_if_changed(2).await; // Different value, broadcasts
assert_eq!(rx.recv().await.unwrap(), 2);Sourcepub async fn with<R, F>(&self, f: F) -> R
pub async fn with<R, F>(&self, f: F) -> R
Runs a read-only closure on the actor’s value and returns the result. Does not broadcast.
This is useful for reading parts of the actor state without cloning the entire value, and works with non-Clone types.
§Examples
let handle = Handle::new(vec![1, 2, 3]);
// Extract just what you need, without cloning the whole Vec
let len = handle.with(|v| v.len()).await;
assert_eq!(len, 3);
let first = handle.with(|v| v.first().copied()).await;
assert_eq!(first, Some(1));Sourcepub async fn with_mut<R, F>(&self, f: F) -> R
pub async fn with_mut<R, F>(&self, f: F) -> R
Runs a closure on the actor’s value mutably and returns the result.
This is useful for atomic read-modify-return operations without
defining a dedicated #[actify] method.
Note: This always broadcasts after the closure returns, even if
the closure did not actually mutate anything. Use Handle::with
for read-only access that does not broadcast.
§Examples
let handle = Handle::new(vec![1, 2, 3]);
let mut rx = handle.subscribe();
// Mutate and return a result in one atomic operation
let popped = handle.with_mut(|v| v.pop()).await;
assert_eq!(popped, Some(3));
assert_eq!(handle.get().await, vec![1, 2]);
// The mutation triggered a broadcast
assert!(rx.try_recv().is_ok());Source§impl<T, V: Clone + Send + Sync + 'static> Handle<T, V>
impl<T, V: Clone + Send + Sync + 'static> Handle<T, V>
Sourcepub fn create_cache_from(&self, initial_value: V) -> Cache<V>
pub fn create_cache_from(&self, initial_value: V) -> Cache<V>
Creates a Cache initialized with the given value that locally synchronizes
with broadcasted updates from the actor.
As it is not initialized with the current value, any updates before construction are missed.
See also Handle::create_cache for a cache initialized with the current actor value,
or Handle::create_cache_from_default to start from V::default().
§Examples
let handle = Handle::new(10);
let mut cache = handle.create_cache_from(42);
assert_eq!(cache.get_current(), &42);
handle.set(99).await;
assert_eq!(cache.get_newest(), &99);Source§impl<T, V: Default + Clone + Send + Sync + 'static> Handle<T, V>
impl<T, V: Default + Clone + Send + Sync + 'static> Handle<T, V>
Sourcepub fn create_cache_from_default(&self) -> Cache<V>
pub fn create_cache_from_default(&self) -> Cache<V>
Creates a Cache initialized with V::default() that locally synchronizes
with broadcasted updates from the actor.
As it is not initialized with the current value, any updates before construction are missed.
See also Handle::create_cache for a cache initialized with the current actor value,
or Handle::create_cache_from to start from a custom value.
Source§impl<T, V> Handle<T, V>
impl<T, V> Handle<T, V>
Sourcepub async fn create_cache(&self) -> Cache<V>
pub async fn create_cache(&self) -> Cache<V>
Creates an initialized Cache that locally synchronizes with the remote actor.
As it is initialized with the current value, any updates before construction are included.
See also Handle::create_cache_from_default for a cache that starts from V::default().
Sourcepub async fn spawn_throttle<C, F>(
&self,
client: C,
call: fn(&C, F),
freq: Frequency,
)
pub async fn spawn_throttle<C, F>( &self, client: C, call: fn(&C, F), freq: Frequency, )
Spawns a Throttle that fires given a specified Frequency.
The broadcast type must implement Throttled<F> to
convert the value into the callback argument.
§Examples
struct Logger(Arc<Mutex<Vec<i32>>>);
impl Logger {
fn log(&self, val: i32) { self.0.lock().unwrap().push(val); }
}
let handle = Handle::new(1);
let values = Arc::new(Mutex::new(Vec::new()));
handle.spawn_throttle(Logger(values.clone()), Logger::log, Frequency::OnEvent).await;
handle.set(2).await;
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
// Fires once with the current value on creation, then on each broadcast
assert_eq!(*values.lock().unwrap(), vec![1, 2]);Trait Implementations§
Source§impl<K, V, __V> HashMapHandle<K, V> for Handle<HashMap<K, V>, __V>
Extension methods for Handle<HashMap<K, V>>, exposed as HashMapHandle.
impl<K, V, __V> HashMapHandle<K, V> for Handle<HashMap<K, V>, __V>
Extension methods for Handle<HashMap<K, V>>, exposed as HashMapHandle.
Source§async fn get_key(&self, key: K) -> Option<V>
async fn get_key(&self, key: K) -> Option<V>
Returns a clone of the value corresponding to the key if it exists It is equivalent to the Hashmap get(), but the method name is changed to avoid conflicts with the get() method of the actor in general
§Examples
let handle = Handle::new(HashMap::new());
handle.insert("test", 10).await;
let res = handle.get_key("test").await;
assert_eq!(res, Some(10));Source§async fn insert(&self, key: K, val: V) -> Option<V>
async fn insert(&self, key: K, val: V) -> Option<V>
Inserts a key-value pair into the map.
If the map did not have this key present, None is returned.
If the map did have this key present, the value is updated, and the old value is returned.
In that case the key is not updated.
§Examples
let handle = Handle::new(HashMap::new());
let res = handle.insert("test", 10).await;
assert_eq!(res, None);
let old_value = handle.insert("test", 20).await;
assert_eq!(old_value, Some(10));Source§async fn remove(&self, key: K) -> Option<V>
async fn remove(&self, key: K) -> Option<V>
Removes a key from the map, returning the value at the key if the key was previously in the map.
Equivalent to HashMap::remove.
§Examples
let handle = Handle::new(HashMap::new());
handle.insert("test", 10).await;
let res = handle.remove("test").await;
assert_eq!(res, Some(10));
let res = handle.remove("test").await;
assert_eq!(res, None);Source§async fn clear(&self)
async fn clear(&self)
Clears the map, removing all key-value pairs.
Equivalent to HashMap::clear.
§Examples
let handle = Handle::new(HashMap::new());
handle.insert("test", 10).await;
handle.clear().await;
assert!(handle.is_empty().await);Source§async fn is_empty(&self) -> bool
async fn is_empty(&self) -> bool
Returns true if the map contains no elements.
§Examples
let handle = Handle::new(HashMap::<&str, i32>::new());
assert!(handle.is_empty().await);Source§async fn keys(&self) -> Vec<K>
async fn keys(&self) -> Vec<K>
Returns a Vec of all keys in the map.
Equivalent to HashMap::keys, but collected into a Vec.
§Examples
let handle = Handle::new(HashMap::new());
handle.insert("a", 1).await;
handle.insert("b", 2).await;
let mut keys = handle.keys().await;
keys.sort();
assert_eq!(keys, vec!["a", "b"]);Source§async fn values(&self) -> Vec<V>
async fn values(&self) -> Vec<V>
Returns a Vec of all values in the map.
Equivalent to HashMap::values, but collected into a Vec.
§Examples
let handle = Handle::new(HashMap::new());
handle.insert("a", 1).await;
handle.insert("b", 2).await;
let mut values = handle.values().await;
values.sort();
assert_eq!(values, vec![1, 2]);Source§impl<K, __V> HashSetHandle<K> for Handle<HashSet<K>, __V>
Extension methods for Handle<HashSet<K>>, exposed as HashSetHandle.
impl<K, __V> HashSetHandle<K> for Handle<HashSet<K>, __V>
Extension methods for Handle<HashSet<K>>, exposed as HashSetHandle.
Source§async fn insert(&self, val: K) -> bool
async fn insert(&self, val: K) -> bool
Adds a value to the set. Returns whether the value was newly inserted. That is:
- If the set did not previously contain this value, true is returned.
- If the set already contained this value, false is returned, and the set is not modified: original value is not replaced, and the value passed as argument is dropped.
§Examples
let handle = Handle::new(HashSet::new());
let res = handle.insert(10).await;
assert!(res);
let res = handle.insert(10).await;
assert!(!res);Source§impl<T, __V> OptionHandle<T> for Handle<Option<T>, __V>
An implementation of the ActorOption extension trait for the standard Option.
This extension trait is made available on the Handle through the actify macro
as OptionHandle.
Within the actor these methods are invoked, which in turn just extend the functionality provided by the std library.
impl<T, __V> OptionHandle<T> for Handle<Option<T>, __V>
An implementation of the ActorOption extension trait for the standard Option.
This extension trait is made available on the Handle through the actify macro
as OptionHandle.
Within the actor these methods are invoked, which in turn just extend the functionality provided by the std library.
Source§impl<T, __V> VecHandle<T> for Handle<Vec<T>, __V>
Extension methods for Handle<Vec<T>>, exposed as VecHandle.
impl<T, __V> VecHandle<T> for Handle<Vec<T>, __V>
Extension methods for Handle<Vec<T>>, exposed as VecHandle.
Source§async fn push(&self, value: T)
async fn push(&self, value: T)
Appends an element to the back of a collection.
§Examples
let handle = Handle::new(vec![1, 2]);
handle.push(100).await;
assert_eq!(handle.get().await, vec![1, 2, 100]);Source§async fn is_empty(&self) -> bool
async fn is_empty(&self) -> bool
Returns true if the vector contains no elements.
§Examples
let handle = Handle::new(Vec::<i32>::new());
assert!(handle.is_empty().await);