2 * Copyright 2017-present Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <folly/futures/Future.h>
20 #include <folly/futures/SharedPromise.h>
25 * FutureSplitter provides a `getFuture()' method which can be called multiple
26 * times, returning a new Future each time. These futures are called-back when
27 * the original Future passed to the FutureSplitter constructor completes. Calls
28 * to `getFuture()' after that time return a completed Future.
30 * Note that while the Futures from `getFuture()' depend on the completion of
31 * the original Future they do not inherit any other properties such as
32 * Executors passed to `via' etc.
35 class FutureSplitter {
38 * Default constructor for convenience only. It is an error to call
39 * `getFuture()` on a default-constructed FutureSplitter which has not had
40 * a correctly-constructed FutureSplitter copy- or move-assigned into it.
42 FutureSplitter() = default;
45 * Provide a way to split a Future<T>.
47 explicit FutureSplitter(Future<T>&& future)
48 : promise_(std::make_shared<SharedPromise<T>>()) {
49 future.then([promise = promise_](Try<T> && theTry) {
50 promise->setTry(std::move(theTry));
55 * This can be called an unlimited number of times per FutureSplitter.
57 Future<T> getFuture() {
58 if (promise_ == nullptr) {
59 throwNoFutureInSplitter();
61 return promise_->getFuture();
65 std::shared_ptr<SharedPromise<T>> promise_;
69 * Convenience function, allowing us to exploit template argument deduction to
70 * improve readability.
73 FutureSplitter<T> splitFuture(Future<T>&& future) {
74 return FutureSplitter<T>{std::move(future)};