Expand description
§Arc Guard
This crate1 provides the ArcGuard
class, which is a container for a single object
with lifetime that is bound to that of an Arc
. This is useful for passing around boxed
futures that have a lifetime that is limited to that of the object that created it.
For example, the following does not compile:
use futures::{future::ready,future::BoxFuture,prelude::*};
use std::sync::{Arc,Weak};
use arc_guard::{ArcGuard,ArcGuardExt};
trait PropertyFetcher {
fn fetch(
&self,
key: &str,
) -> BoxFuture<Option<String>>;
}
struct WeakFetcher {
sub_obj: Weak<Box<PropertyFetcher>>,
}
impl PropertyFetcher for WeakFetcher {
fn fetch(&self, key: &str) -> BoxFuture<Option<String>> {
if let Some(arc) = self.sub_obj.upgrade() {
// error[E0515]: cannot return value referencing local variable `arc`
arc.fetch(key).boxed()
} else {
ready(None).boxed()
}
}
}
If you think about it, the fact that rustc
doesn’t like this code makes perfect sense:
because sub_obj
is a weak reference, it could be dropped at any moment, violating the
lifetime guarantee for the return value of fetch()
. To fix this, we need to ensure that
the value we return internally keeps an Arc
reference to the object that created it. That’s
where ArcGuard
comes in:
impl PropertyFetcher for WeakFetcher {
fn fetch(&self, key: &str) -> BoxFuture<Option<String>> {
if let Some(arc) = self.sub_obj.upgrade() {
// Compiles and works!
arc.guard(|x|x.fetch(key)).boxed()
} else {
ready(None).boxed()
}
}
}
§Additional Examples
let mut arc = Arc::new("foobar".to_string());
let guarded = arc.guard(|s| &s.as_str()[3..]);
assert_eq!(guarded, "bar");
// We can't get a mutable instance to the
// string while `guarded` is still around.
assert_eq!(Arc::get_mut(&mut arc), None);
core::mem::drop(guarded);
assert!(Arc::get_mut(&mut arc).is_some());
I would have loved to call this crate
lifeguard
, because it is a “guard” on the lifetime of the contained “head” instance, but sadly that name was already taken. ↩
Structs§
- ArcGuard
- A container for a single object with lifetime that is bound to that of an
Arc
.
Traits§
- ArcGuard
Ext - A convenience trait for
Arc<>
that makes it easier to constructArcGuard<>
instances.