The following struct wraps an address of CacheActor:
#[derive(Clone)]
pub struct CacheLink {
addr: Addr<CacheActor>,
}
The constructor only fills this addr field with an Addr value:
impl CacheLink {
pub fn new(addr: Addr<CacheActor>) -> Self {
Self { addr }
}
}
We need a CacheLink wrapping struct to add methods to get access to caching features, but need to hide the implementation details and message interchange. First, we need a method to get cached values:
pub fn get_value(&self, path: &str) -> Box<Future<Item = Option<Vec<u8>>, Error = Error>> {
let msg = GetValue {
path: path.to_owned(),
};
let fut = self.addr.send(msg)
.from_err::<Error>()
.and_then(|x| x.map_err(Error::from));
Box::new(fut)
}
The preceding function creates a new GetValue message with a path inside, and sends this message to Addr, contained in CacheLink. After this, it waits for the result. The function returns this interaction sequence as a boxed Future.
The next method is implemented in a similar way—the set_value method sets a new value to a cache by sending a SetValue message to CacheActor:
pub fn set_value(&self, path: &str, value: &[u8]) -> Box<Future<Item = (), Error = Error>> {
let msg = SetValue {
path: path.to_owned(),
content: value.to_owned(),
};
let fut = self.addr.send(msg)
.from_err::<Error>()
.and_then(|x| x.map_err(Error::from));
Box::new(fut)
}
To compose a message, we use a path and a bytes array reference converted into a Vec<u8> value. Now, we can use CacheActor and CacheLink in a server implementation.