promising-future 0.2.4

Implementation of Promise/Future pairs.
Documentation

Futures and Promises

Quick example:

# use ::promising_future::future_promise;
# use std::time::Duration;
# #[allow(unused_variables)]
# use std::thread;
let (fut, prom) = future_promise();

// A time-consuming process
thread::spawn(|| { thread::sleep(Duration::from_millis(100)); prom.set(123) });

// do something when the value is ready
let fut = fut.then(|v| v + 1);

// Wait for the final result
assert_eq!(fut.value(), Some(124));

This module implements a pair of concepts: Futures - a read-only placeholder for a variable whose value may not yet be known, and Promises - a write-once container which sets the value.

A Future may either be "resolved" or "unresolved". An unresolved Future still has a pending Promise for it. It becomes resolved once the Promise is complete. Once resolved, it will have a value if the Promise was fulfilled (ie, set a value), or no value if the Promise was unfulfilled (ie, dropped without setting a value).

A Promise is either "pending" or "complete". A pending Promise is simply a live value of type Promise<T>. It can be fulfilled by setting a value, which consumes the Promise, completing it. Alternatively it can be completed unfulfilled by simply dropping the value without ever calling set on it.

A Future can also be created already resolved (ie, not paired with a Promise). This is useful for lifting values into the Promise/Future domain.

Futures may be chained in two ways. The most general way is with callback, which takes a Future and a function to act on the value when it becomes available. This function is called within the same context that completed the Promise so if the function blocks it will block that context. The callback is passed another Promise to take the return of the callback, which may be fulfilled or unfulfilled within the callback, or passed on somewhere else.

Using callback directly can be a little cumbersome, so there are a couple of helpers. then simply calls a synchronous callback function and uses its return to fulfill the value. The function must be run within the Promise context, so it should probably be quick.

Alternatively chain - like then - will take a function to act on the resolved future value. However, unlike then it runs it in its own thread, so it can be arbitrarily time-consuming. The variant chain_with allows the thread creation to be controlled, so that thread pools may be used, for example.

Groups of Futures can be acted upon together. all takes an iterator of Future<T>s, and returns a Future<Iterator<T>>, so that its possible to wait for multiple Futures to be resolved.

Similarly, any returns the first available value of an iterator of Futures, discarding all the other values.

More generally, FutureStream provides a mechanism to wait on an arbitrary number of Futures and incrementally acquiring their values as they become available.

If a Future is dropped while its corresponding Promise is still pending, then any value it does produce will be discarded. The Promise be queried with its canceled method to see if a corresponding Future still exists; if not, it may choose to abort some time-consuming process rather than have its output simply discarded.