Skip to content
An asynchronous leased value
Rust
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
tests
.gitignore
.travis.yml
Cargo.toml
README.md
README.tpl

README.md

async-lease

Crates.io Documentation Build Status Codecov

An asynchronous, atomic option type intended for use with methods that move self.

This module provides Lease, a type that acts similarly to an asynchronous Mutex, with one major difference: it expects you to move the leased item by value, and then return it when you are done. You can think of a Lease as an atomic, asynchronous Option type, in which we can take the value only if no-one else has currently taken it, and where we are notified when the value has returned so we can try to take it again.

This type is intended for use with methods that take self by value, and eventually, at some later point in time, return that Self for future use. This tends to happen particularly often in future-related contexts. For example, consider the following method for a hypothetical, non-pipelined connection type:

impl Connection {
    fn get(self, key: i64) -> impl Future<Item = (i64, Self), Error = Error>;
}

Let's say you want to expose an interface that does not consume self, but instead has a poll_ready method that checks whether the connection is ready to receive another request:

impl MyConnection {
    fn poll_ready(&mut self) -> Poll<(), Error = Error>;
    fn call(&mut self, key: i64) -> impl Future<Item = i64, Error = Error>;
}

Lease allows you to do this. Specifically, poll_ready attempts to acquire the lease using Lease::poll_acquire, and call transfers that lease into the returned future. When the future eventually resolves, we restore the leased value so that poll_ready returns Ready again to anyone else who may want to take the value. The example above would thus look like this:

impl MyConnection {
    fn poll_ready(&mut self) -> Poll<(), Error = Error> {
        self.lease.poll_acquire()
    }

    fn call(&mut self, key: i64) -> impl Future<Item = i64, Error = Error> {
        // We want to transfer the lease into the future
        // and leave behind an unacquired lease.
        let mut lease = self.lease.transfer();
        lease.take().get(key).map(move |(v, connection)| {
            // Give back the connection for other callers.
            // After this, `poll_ready` may return `Ok(Ready)` again.
            lease.restore(connection);
            // And yield just the value.
            v
        })
    }
}
You can’t perform that action at this time.