#future #branch #explicit #machines #state #state-machine #construction

union-future

Macro that allows easy construction of explicit Future state machines that result from branching

2 releases

Uses old Rust 2015

0.1.1 Dec 27, 2016
0.1.0 Dec 27, 2016

#7 in #state-machines

MIT license

10KB
84 lines

Union Futures

When writing asynchronous code with the wonderful futures library, it is sometimes necessary to write code that branches. For example, your code may have an immediate answer some of the time, in which case you want to return a future that resolves immediately, or it may need to call the database if an immediate answer is not available.

As discussed in the tutorial, there are multiple options for this scenario, with the most popular being to create a BoxedFuture. There are downsides to this approach, such as runtime allocation of the trait object. The BoxedFuture approach is popular because it is highly ergonomic (the future trait has a method .boxed() that almost encourages the approach).

However, in high performance scenarios or when exposing a library, explicit state machines are the preferred approach to building futures. This library makes it easy to write ergonomic code that is also efficient.

#[macro_use]
extern crate union_future;
extern crate futures;

use futures::*;
use futures::future::*;

// Macro will create the enum and necessary trait implementations
// for the QueryFuture. This enum will have 2 variants: Cached and Db.
union_future!(QueryFuture<u64, DbError>,
      Cached => FutureResult<u64, DbError>,
      Db => DbQueryFuture<u64>);

// Example code that branches, using the future created by the macro
pub fn query(db: &Db, key: &str) -> QueryFuture {
    if let Some(cached_val) = check_local_cache(key) {
        QueryFuture::Cached(ok(cached_val))
    } else {
        query_db(db, key).into()
    }
}

fn check_local_cache(key: &str) -> Option<u64> {
    // ...
}

fn query_db(db: &Db, key: &str) -> DbQueryFuture<u64> {
    // ...
}

Installation

First, add this to your Cargo.toml:

[dependencies]
union-future = "0.1"
futures = "0.1"

Dependencies

~54KB