Is it possible to loop over a Vec
, calling a method that returns a Future
on each, and build a chain of Future
s, to be evaluated (eventually) by the consumer? Whether to execute the later Future
s would depend on the outcome of the earlier Future
s in the Vec
.
To clarify:
I'm working on an application that can fetch data from an arbitrary set of upstream sources.
Requesting data would check with each of the sources, in turn. If the first source had an error (Err
), or did not have the data available (None
), then the second source would be tried, and so on.
Each source should be tried exactly once, and no source should be tried until all of the sources before have returned their results. Errors are logged, but otherwise ignored, passing the query to the next upstream data source.
I have some working code that does this for fetching metadata:
/// Attempts to read/write data to various external sources. These are
/// nested types, because a data source may exist as both a reader and a writer
struct StoreManager {
/// Upstream data sources
readers: Vec<Rc<RefCell<StoreRead>>>,
/// Downstream data sinks
writers: Vec<Rc<RefCell<StoreWrite>>>,
}
impl StoreRead for StoreManager {
fn metadata(self: &Self, id: &Identifier) -> Box<Future<Option<Metadata>, Error>> {
Box::new(ok(self.readers
.iter()
.map(|store| {
executor::block_on(store.borrow().metadata(id)).unwrap_or_else(|err| {
error!("Error on metadata(): {:?}", err);
None
})
})
.find(Option::is_some)
.unwrap_or(None)))
}
}
Aside from my unhappiness with all of the Box
and Rc/RefCell
nonsense, my real concern is with the executor::block_on()
call. It blocks, waiting for each Future
to return a result, before continuing to the next.
Given that it's possible to call fn_returning_future().or_else(|_| other_fn())
and so on, is it possible to build up a dynamic chain like this? Or is it a requirement to fully evaluate each Future
in the iterator before moving to the next?
Stream
instead. Quote: "If Future is an asynchronous version of Result, then Stream is an asynchronous version of Iterator." and you want to iterate :) – TabletVec
, calling a method that returns aFuture
on each, and build a chain ofFutures
, to be evaluated (eventually) by the consumer?". – Spacing