1 /*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #pragma once
18
19 #include <algorithm>
20 #include <exception>
21 #include <functional>
22 #include <memory>
23 #include <type_traits>
24 #include <utility>
25 #include <vector>
26
27 #include <folly/Optional.h>
28 #include <folly/Portability.h>
29 #include <folly/ScopeGuard.h>
30 #include <folly/Try.h>
31 #include <folly/Unit.h>
32 #include <folly/Utility.h>
33 #include <folly/executors/DrivableExecutor.h>
34 #include <folly/executors/TimedDrivableExecutor.h>
35 #include <folly/experimental/coro/Traits.h>
36 #if !defined(FOLLY_DISABLE_FUTURE_FIBERS_BATON)
37 #include <folly/fibers/Baton.h>
38 #endif
39 #include <folly/functional/Invoke.h>
40 #include <folly/futures/Portability.h>
41 #include <folly/futures/Promise.h>
42 #include <folly/futures/detail/Types.h>
43 #include <folly/lang/Exception.h>
44
45 // boring predeclarations and details
46 #include <folly/futures/Future-pre.h>
47
48 namespace folly {
49
50 class FOLLY_EXPORT FutureException : public std::logic_error {
51 public:
52 using std::logic_error::logic_error;
53 };
54
55 class FOLLY_EXPORT FutureInvalid : public FutureException {
56 public:
FutureInvalid()57 FutureInvalid() : FutureException("Future invalid") {}
58 };
59
60 /// At most one continuation may be attached to any given Future.
61 ///
62 /// If a continuation is attached to a future to which another continuation has
63 /// already been attached, then an instance of FutureAlreadyContinued will be
64 /// thrown instead.
65 class FOLLY_EXPORT FutureAlreadyContinued : public FutureException {
66 public:
FutureAlreadyContinued()67 FutureAlreadyContinued() : FutureException("Future already continued") {}
68 };
69
70 class FOLLY_EXPORT FutureNotReady : public FutureException {
71 public:
FutureNotReady()72 FutureNotReady() : FutureException("Future not ready") {}
73 };
74
75 class FOLLY_EXPORT FutureCancellation : public FutureException {
76 public:
FutureCancellation()77 FutureCancellation() : FutureException("Future was cancelled") {}
78 };
79
80 class FOLLY_EXPORT FutureTimeout : public FutureException {
81 public:
FutureTimeout()82 FutureTimeout() : FutureException("Timed out") {}
83 };
84
85 class FOLLY_EXPORT FuturePredicateDoesNotObtain : public FutureException {
86 public:
FuturePredicateDoesNotObtain()87 FuturePredicateDoesNotObtain()
88 : FutureException("Predicate does not obtain") {}
89 };
90
91 class FOLLY_EXPORT FutureNoTimekeeper : public FutureException {
92 public:
FutureNoTimekeeper()93 FutureNoTimekeeper() : FutureException("No timekeeper available") {}
94 };
95
96 class FOLLY_EXPORT FutureNoExecutor : public FutureException {
97 public:
FutureNoExecutor()98 FutureNoExecutor() : FutureException("No executor provided to via") {}
99 };
100
101 template <class T>
102 class Future;
103
104 template <class T>
105 class SemiFuture;
106
107 template <class T>
108 class FutureSplitter;
109
110 namespace futures {
111 namespace detail {
112 template <class T>
113 class FutureBase {
114 protected:
115 using Core = futures::detail::Core<T>;
116
117 public:
118 typedef T value_type;
119
120 /// Construct from a value (perfect forwarding)
121 ///
122 /// Postconditions:
123 ///
124 /// - `valid() == true`
125 /// - `isReady() == true`
126 /// - `hasValue() == true`
127 template <
128 class T2 = T,
129 typename = typename std::enable_if<
130 !isFuture<typename std::decay<T2>::type>::value &&
131 !isSemiFuture<typename std::decay<T2>::type>::value &&
132 std::is_constructible<Try<T>, T2>::value>::type>
133 /* implicit */ FutureBase(T2&& val);
134
135 /// Construct a (logical) FutureBase-of-void.
136 ///
137 /// Postconditions:
138 ///
139 /// - `valid() == true`
140 /// - `isReady() == true`
141 /// - `hasValue() == true`
142 template <class T2 = T>
143 /* implicit */ FutureBase(
144 typename std::enable_if<std::is_same<Unit, T2>::value>::type*);
145
146 template <
147 class... Args,
148 typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
149 type = 0>
FutureBase(in_place_t,Args &&...args)150 explicit FutureBase(in_place_t, Args&&... args)
151 : core_(Core::make(in_place, static_cast<Args&&>(args)...)) {}
152
153 FutureBase(FutureBase<T> const&) = delete;
154 FutureBase(SemiFuture<T>&&) noexcept;
155 FutureBase(Future<T>&&) noexcept;
156
157 // not copyable
158 FutureBase(Future<T> const&) = delete;
159 FutureBase(SemiFuture<T> const&) = delete;
160
161 ~FutureBase();
162
163 /// true if this has a shared state;
164 /// false if this has been either moved-out or created without a shared state.
valid()165 bool valid() const noexcept { return core_ != nullptr; }
166
167 /// Returns a reference to the result value if it is ready, with a reference
168 /// category and const-qualification like those of the future.
169 ///
170 /// Does not `wait()`; see `get()` for that.
171 ///
172 /// Preconditions:
173 ///
174 /// - `valid() == true` (else throws FutureInvalid)
175 /// - `isReady() == true` (else throws FutureNotReady)
176 ///
177 /// Postconditions:
178 ///
179 /// - If an exception has been captured (i.e., if `hasException() == true`),
180 /// throws that exception.
181 /// - This call does not mutate the future's value.
182 /// - However calling code may mutate that value (including moving it out by
183 /// move-constructing or move-assigning another value from it), for
184 /// example, via the `&` or the `&&` overloads or via casts.
185 T& value() &;
186 T const& value() const&;
187 T&& value() &&;
188 T const&& value() const&&;
189
190 /// Returns a reference to the result's Try if it is ready, with a reference
191 /// category and const-qualification like those of the future.
192 ///
193 /// Does not `wait()`; see `get()` for that.
194 ///
195 /// Preconditions:
196 ///
197 /// - `valid() == true` (else throws FutureInvalid)
198 /// - `isReady() == true` (else throws FutureNotReady)
199 ///
200 /// Postconditions:
201 ///
202 /// - This call does not mutate the future's result.
203 /// - However calling code may mutate that result (including moving it out by
204 /// move-constructing or move-assigning another result from it), for
205 /// example, via the `&` or the `&&` overloads or via casts.
206 Try<T>& result() &;
207 Try<T> const& result() const&;
208 Try<T>&& result() &&;
209 Try<T> const&& result() const&&;
210
211 /// True when the result (or exception) is ready; see value(), result(), etc.
212 ///
213 /// Preconditions:
214 ///
215 /// - `valid() == true` (else throws FutureInvalid)
216 bool isReady() const;
217
218 /// True if the result is a value (not an exception) on a future for which
219 /// isReady returns true.
220 ///
221 /// Equivalent to result().hasValue()
222 ///
223 /// Preconditions:
224 ///
225 /// - `valid() == true` (else throws FutureInvalid)
226 /// - `isReady() == true` (else throws FutureNotReady)
227 bool hasValue() const;
228
229 /// True if the result is an exception (not a value) on a future for which
230 /// isReady returns true.
231 ///
232 /// Equivalent to result().hasException()
233 ///
234 /// Preconditions:
235 ///
236 /// - `valid() == true` (else throws FutureInvalid)
237 /// - `isReady() == true` (else throws FutureNotReady)
238 bool hasException() const;
239
240 /// Returns either an Optional holding the result or an empty Optional
241 /// depending on whether or not (respectively) the promise has been
242 /// fulfilled (i.e., `isReady() == true`).
243 ///
244 /// Preconditions:
245 ///
246 /// - `valid() == true` (else throws FutureInvalid)
247 ///
248 /// Postconditions:
249 ///
250 /// - `valid() == true` (note however that this moves-out the result when
251 /// it returns a populated `Try<T>`, which effects any subsequent use of
252 /// that result, e.g., `poll()`, `result()`, `value()`, `get()`, etc.)
253 Optional<Try<T>> poll();
254
255 /// This is not the method you're looking for.
256 ///
257 /// This needs to be public because it's used by make* and when*, and it's
258 /// not worth listing all those and their fancy template signatures as
259 /// friends. But it's not for public consumption.
260 template <class F>
261 void setCallback_(F&& func, InlineContinuation = InlineContinuation::forbid);
262
263 /// Provides a threadsafe back-channel so the consumer's thread can send an
264 /// interrupt-object to the producer's thread.
265 ///
266 /// If the promise-holder registers an interrupt-handler and consumer thread
267 /// raises an interrupt early enough (details below), the promise-holder
268 /// will typically halt its work, fulfilling the future with an exception
269 /// or some special non-exception value.
270 ///
271 /// However this interrupt request is voluntary, asynchronous, & advisory:
272 ///
273 /// - Voluntary: the producer will see the interrupt only if the producer uses
274 /// a `Promise` object and registers an interrupt-handler;
275 /// see `Promise::setInterruptHandler()`.
276 /// - Asynchronous: the producer will see the interrupt only if `raise()` is
277 /// called before (or possibly shortly after) the producer is done producing
278 /// its result, which is asynchronous with respect to the call to `raise()`.
279 /// - Advisory: the producer's interrupt-handler can do whatever it wants,
280 /// including ignore the interrupt or perform some action other than halting
281 /// its producer-work.
282 ///
283 /// Guidelines:
284 ///
285 /// - It is ideal if the promise-holder can both halt its work and fulfill the
286 /// promise early, typically with the same exception that was delivered to
287 /// the promise-holder in the form of an interrupt.
288 /// - If the promise-holder does not do this, and if it holds the promise
289 /// alive for a long time, then the whole continuation chain will not be
290 /// invoked and the whole future chain will be kept alive for that long time
291 /// as well.
292 /// - It is also ideal if the promise-holder can invalidate the promise.
293 /// - The promise-holder must also track whether it has set a result in the
294 /// interrupt handler so that it does not attempt to do so outside the
295 /// interrupt handler, and must track whether it has set a result in its
296 /// normal flow so that it does not attempt to do so in the interrupt
297 /// handler, since setting a result twice is an error. Because the interrupt
298 /// handler can be invoked in some other thread, this tracking may have to
299 /// be done with some form of concurrency control.
300 ///
301 /// Preconditions:
302 ///
303 /// - `valid() == true` (else throws FutureInvalid)
304 ///
305 /// Postconditions:
306 ///
307 /// - has no visible effect if `raise()` was previously called on `this` or
308 /// any other Future/SemiFuture that uses the same shared state as `this`.
309 /// - has no visible effect if the producer never (either in the past or in
310 /// the future) registers an interrupt-handler.
311 /// - has no visible effect if the producer fulfills its promise (sets the
312 /// result) before (or possibly also shortly after) receiving the interrupt.
313 /// - otherwise the promise-holder's interrupt-handler is called, passing the
314 /// exception (within an `exception_wrapper`).
315 ///
316 /// The specific thread used to invoke the producer's interrupt-handler (if
317 /// it is called at all) depends on timing:
318 ///
319 /// - if the interrupt-handler is registered prior to `raise()` (or possibly
320 /// concurrently within the call to `raise()`), the interrupt-handler will
321 /// be executed using this current thread within the call to `raise()`.
322 /// - if the interrupt-handler is registered after `raise()` (and possibly
323 /// concurrently within the call to `raise()`), the interrupt-handler will
324 /// be executed using the producer's thread within the call to
325 /// `Promise::setInterruptHandler()`.
326 ///
327 /// Synchronizes between `raise()` (in the consumer's thread)
328 /// and `Promise::setInterruptHandler()` (in the producer's thread).
329 void raise(exception_wrapper interrupt);
330
331 /// Raises the specified exception-interrupt.
332 /// See `raise(exception_wrapper)` for details.
333 template <class E>
raise(E && exception)334 void raise(E&& exception) {
335 raise(make_exception_wrapper<typename std::remove_reference<E>::type>(
336 static_cast<E&&>(exception)));
337 }
338
339 /// Raises a FutureCancellation interrupt.
340 /// See `raise(exception_wrapper)` for details.
cancel()341 void cancel() { raise(FutureCancellation()); }
342
343 protected:
344 friend class Promise<T>;
345 template <class>
346 friend class SemiFuture;
347 template <class>
348 friend class Future;
349
350 // Throws FutureInvalid if there is no shared state object; else returns it
351 // by ref.
352 //
353 // Implementation methods should usually use this instead of `this->core_`.
354 // The latter should be used only when you need the possibly-null pointer.
getCore()355 Core& getCore() { return getCoreImpl(*this); }
getCore()356 Core const& getCore() const { return getCoreImpl(*this); }
357
358 template <typename Self>
decltype(auto)359 static decltype(auto) getCoreImpl(Self& self) {
360 if (!self.core_) {
361 throw_exception<FutureInvalid>();
362 }
363 return *self.core_;
364 }
365
getCoreTryChecked()366 Try<T>& getCoreTryChecked() { return getCoreTryChecked(*this); }
getCoreTryChecked()367 Try<T> const& getCoreTryChecked() const { return getCoreTryChecked(*this); }
368
369 template <typename Self>
decltype(auto)370 static decltype(auto) getCoreTryChecked(Self& self) {
371 auto& core = self.getCore();
372 if (!core.hasResult()) {
373 throw_exception<FutureNotReady>();
374 }
375 return core.getTry();
376 }
377
378 // shared core state object
379 // usually you should use `getCore()` instead of directly accessing `core_`.
380 Core* core_;
381
FutureBase(Core * obj)382 explicit FutureBase(Core* obj) : core_(obj) {}
383
384 explicit FutureBase(futures::detail::EmptyConstruct) noexcept;
385
386 void detach();
387
388 void throwIfInvalid() const;
389 void throwIfContinued() const;
390
391 void assign(FutureBase<T>&& other) noexcept;
392
getExecutor()393 Executor* getExecutor() const { return getCore().getExecutor(); }
394
getDeferredExecutor()395 DeferredExecutor* getDeferredExecutor() const {
396 return getCore().getDeferredExecutor();
397 }
398
399 // Sets the Executor within the Core state object of `this`.
400 // Must be called either before attaching a callback or after the callback
401 // has already been invoked, but not concurrently with anything which might
402 // trigger invocation of the callback.
setExecutor(futures::detail::KeepAliveOrDeferred x)403 void setExecutor(futures::detail::KeepAliveOrDeferred x) {
404 getCore().setExecutor(std::move(x));
405 }
406
407 // Variant: returns a value
408 // e.g. f.thenTry([](Try<T> t){ return t.value(); });
409 template <typename F, typename R>
410 typename std::enable_if<!R::ReturnsFuture::value, typename R::Return>::type
411 thenImplementation(F&& func, R, InlineContinuation);
412
413 // Variant: returns a Future
414 // e.g. f.thenTry([](Try<T> t){ return makeFuture<T>(t); });
415 template <typename F, typename R>
416 typename std::enable_if<R::ReturnsFuture::value, typename R::Return>::type
417 thenImplementation(F&& func, R, InlineContinuation);
418 };
419 template <class T>
420 Future<T> convertFuture(SemiFuture<T>&& sf, const Future<T>& f);
421
422 class DeferredExecutor;
423
424 template <typename T>
425 DeferredExecutor* getDeferredExecutor(SemiFuture<T>& future);
426
427 template <typename T>
428 futures::detail::DeferredWrapper stealDeferredExecutor(SemiFuture<T>& future);
429 } // namespace detail
430
431 // Detach the SemiFuture by scheduling work onto exec.
432 template <class T>
433 void detachOn(folly::Executor::KeepAlive<> exec, folly::SemiFuture<T>&& fut);
434
435 // Detach the SemiFuture by detaching work onto the global CPU executor.
436 template <class T>
437 void detachOnGlobalCPUExecutor(folly::SemiFuture<T>&& fut);
438
439 // Detach the SemiFuture onto the global CPU executor after dur.
440 // This will only hold a weak ref to the global executor and during
441 // shutdown will cleanly drop the work.
442 template <class T>
443 void maybeDetachOnGlobalExecutorAfter(
444 HighResDuration dur, folly::SemiFuture<T>&& fut);
445
446 // Detach the SemiFuture with no executor.
447 // NOTE: If there is deferred work of any sort on this SemiFuture
448 // will leak and not be run.
449 // Use at your own risk.
450 template <class T>
451 void detachWithoutExecutor(folly::SemiFuture<T>&& fut);
452 } // namespace futures
453
454 /// The interface (along with Future) for the consumer-side of a
455 /// producer/consumer pair.
456 ///
457 /// Future vs. SemiFuture:
458 ///
459 /// - The consumer-side should generally start with a SemiFuture, not a Future.
460 /// - Example, when a library creates and returns a future, it should usually
461 /// return a `SemiFuture`, not a Future.
462 /// - Reason: so the thread policy for continuations (`.thenValue`, etc.) can be
463 /// specified by the library's caller (using `.via()`).
464 /// - A SemiFuture is converted to a Future using `.via()`.
465 /// - Use `makePromiseContract()` when creating both a Promise and an associated
466 /// SemiFuture/Future.
467 ///
468 /// When practical, prefer SemiFuture/Future's nonblocking style/pattern:
469 ///
470 /// - the nonblocking style uses continuations, e.g., `.thenValue`, etc.; the
471 /// continuations are deferred until the result is available.
472 /// - the blocking style blocks until complete, e.g., `.wait()`, `.get()`, etc.
473 /// - the two styles cannot be mixed within the same future; use one or the
474 /// other.
475 ///
476 /// SemiFuture/Future also provide a back-channel so an interrupt can
477 /// be sent from consumer to producer; see SemiFuture/Future's `raise()`
478 /// and Promise's `setInterruptHandler()`.
479 ///
480 /// The consumer-side SemiFuture/Future objects should generally be accessed
481 /// via a single thread. That thread is referred to as the 'consumer thread.'
482 template <class T>
483 class SemiFuture : private futures::detail::FutureBase<T> {
484 private:
485 using Base = futures::detail::FutureBase<T>;
486 using DeferredExecutor = futures::detail::DeferredExecutor;
487 using TimePoint = std::chrono::system_clock::time_point;
488
489 public:
490 ~SemiFuture();
491
492 /// Creates/returns an invalid SemiFuture, that is, one with no shared state.
493 ///
494 /// Postcondition:
495 ///
496 /// - `RESULT.valid() == false`
497 static SemiFuture<T> makeEmpty();
498
499 /// Type of the value that the producer, when successful, produces.
500 using typename Base::value_type;
501
502 /// Construct a SemiFuture from a value (perfect forwarding)
503 ///
504 /// Postconditions:
505 ///
506 /// - `valid() == true`
507 /// - `isReady() == true`
508 /// - `hasValue() == true`
509 /// - `hasException() == false`
510 /// - `value()`, `get()`, `result()` will return the forwarded `T`
511 template <
512 class T2 = T,
513 typename = typename std::enable_if<
514 !isFuture<typename std::decay<T2>::type>::value &&
515 !isSemiFuture<typename std::decay<T2>::type>::value &&
516 std::is_constructible<Try<T>, T2>::value>::type>
SemiFuture(T2 && val)517 /* implicit */ SemiFuture(T2&& val) : Base(static_cast<T2&&>(val)) {}
518
519 /// Construct a (logical) SemiFuture-of-void.
520 ///
521 /// Postconditions:
522 ///
523 /// - `valid() == true`
524 /// - `isReady() == true`
525 /// - `hasValue() == true`
526 template <class T2 = T>
527 /* implicit */ SemiFuture(
528 typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr)
Base(p)529 : Base(p) {}
530
531 /// Construct a SemiFuture from a `T` constructed from `args`
532 ///
533 /// Postconditions:
534 ///
535 /// - `valid() == true`
536 /// - `isReady() == true`
537 /// - `hasValue() == true`
538 /// - `hasException() == false`
539 /// - `value()`, `get()`, `result()` will return the newly constructed `T`
540 template <
541 class... Args,
542 typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
543 type = 0>
SemiFuture(in_place_t,Args &&...args)544 explicit SemiFuture(in_place_t, Args&&... args)
545 : Base(in_place, static_cast<Args&&>(args)...) {}
546
547 SemiFuture(SemiFuture<T> const&) = delete;
548 // movable
549 SemiFuture(SemiFuture<T>&&) noexcept;
550 // safe move-constructabilty from Future
551 /* implicit */ SemiFuture(Future<T>&&) noexcept;
552
553 using Base::cancel;
554 using Base::hasException;
555 using Base::hasValue;
556 using Base::isReady;
557 using Base::poll;
558 using Base::raise;
559 using Base::result;
560 using Base::setCallback_;
561 using Base::valid;
562 using Base::value;
563
564 SemiFuture& operator=(SemiFuture const&) = delete;
565 SemiFuture& operator=(SemiFuture&&) noexcept;
566 SemiFuture& operator=(Future<T>&&) noexcept;
567
568 /// Blocks until the promise is fulfilled, either by value (which is returned)
569 /// or exception (which is thrown).
570 ///
571 /// Preconditions:
572 ///
573 /// - `valid() == true` (else throws FutureInvalid)
574 /// - must not have a continuation, e.g., via `.thenValue()` or similar
575 ///
576 /// Postconditions:
577 ///
578 /// - `valid() == false`
579 T get() &&;
580
581 /// Blocks until the semifuture is fulfilled, or until `dur` elapses. Returns
582 /// the value (moved-out), or throws the exception (which might be a
583 /// FutureTimeout exception).
584 ///
585 /// Preconditions:
586 ///
587 /// - `valid() == true` (else throws FutureInvalid)
588 ///
589 /// Postconditions:
590 ///
591 /// - `valid() == false`
592 T get(HighResDuration dur) &&;
593
594 /// Blocks until the future is fulfilled. Returns the Try of the result
595 /// (moved-out).
596 ///
597 /// Preconditions:
598 ///
599 /// - `valid() == true` (else throws FutureInvalid)
600 ///
601 /// Postconditions:
602 ///
603 /// - `valid() == false`
604 Try<T> getTry() &&;
605
606 /// Blocks until the future is fulfilled, or until `dur` elapses.
607 /// Returns the Try of the result (moved-out), or throws FutureTimeout
608 /// exception.
609 ///
610 /// Preconditions:
611 ///
612 /// - `valid() == true` (else throws FutureInvalid)
613 ///
614 /// Postconditions:
615 ///
616 /// - `valid() == false`
617 Try<T> getTry(HighResDuration dur) &&;
618
619 /// Blocks the caller's thread until this Future `isReady()`, i.e., until the
620 /// asynchronous producer has stored a result or exception.
621 ///
622 /// Preconditions:
623 ///
624 /// - `valid() == true` (else throws FutureInvalid)
625 ///
626 /// Postconditions:
627 ///
628 /// - `valid() == true`
629 /// - `isReady() == true`
630 /// - `&RESULT == this`
631 SemiFuture<T>& wait() &;
632
633 /// Blocks the caller's thread until this Future `isReady()`, i.e., until the
634 /// asynchronous producer has stored a result or exception.
635 ///
636 /// Preconditions:
637 ///
638 /// - `valid() == true` (else throws FutureInvalid)
639 ///
640 /// Postconditions:
641 ///
642 /// - `valid() == true` (but the calling code can trivially move-out `*this`
643 /// by assigning or constructing the result into a distinct object).
644 /// - `&RESULT == this`
645 /// - `isReady() == true`
646 SemiFuture<T>&& wait() &&;
647
648 /// Blocks until the future is fulfilled, or `dur` elapses.
649 /// Returns true if the future was fulfilled.
650 ///
651 /// Preconditions:
652 ///
653 /// - `valid() == true` (else throws FutureInvalid)
654 ///
655 /// Postconditions:
656 ///
657 /// - `valid() == false`
658 bool wait(HighResDuration dur) &&;
659
660 /// Returns a Future which will call back on the other side of executor.
661 Future<T> via(Executor::KeepAlive<> executor) &&;
662 Future<T> via(Executor::KeepAlive<> executor, int8_t priority) &&;
663
664 /// Defer work to run on the consumer of the future.
665 /// Function must take a Try as a parameter.
666 /// This work will be run either on an executor that the caller sets on the
667 /// SemiFuture, or inline with the call to .get().
668 ///
669 /// NB: This is a custom method because boost-blocking executors is a
670 /// special-case for work deferral in folly. With more general boost-blocking
671 /// support all executors would boost block and we would simply use some form
672 /// of driveable executor here.
673 ///
674 /// All forms of defer will run the continuation inline with the execution of
675 /// the previous callback in the chain if the callback attached to the
676 /// previous future that triggers execution of func runs on the same executor
677 /// that func would be executed on.
678 ///
679 /// Preconditions:
680 ///
681 /// - `valid() == true` (else throws FutureInvalid)
682 ///
683 /// Postconditions:
684 ///
685 /// - `valid() == false`
686 /// - `RESULT.valid() == true`
687 template <typename F>
688 SemiFuture<typename futures::detail::tryCallableResult<T, F>::value_type>
689 defer(F&& func) &&;
690
691 /// Defer work to run on the consumer of the future.
692 /// Function must take a const Executor::KeepAlive<>& and a Try as parameters.
693 ///
694 /// As for defer(F&& func) except as the first parameter to func a KeepAlive
695 /// representing the executor running the work will be provided.
696 template <typename F>
697 SemiFuture<
698 typename futures::detail::tryExecutorCallableResult<T, F>::value_type>
699 deferExTry(F&& func) &&;
700
701 /// Defer work to run on the consumer of the future.
702 /// Function must take a Try as a parameter.
703 ///
704 /// As for defer(F&& func) but supporting function references.
705 template <typename R, typename... Args>
defer(R (& func)(Args...))706 auto defer(R (&func)(Args...)) && {
707 return std::move(*this).defer(&func);
708 }
709
710 /// Defer for functions taking a T rather than a Try<T>.
711 ///
712 /// All forms of defer will run the continuation inline with the execution of
713 /// the previous callback in the chain if the callback attached to the
714 /// previous future that triggers execution of func runs on the same executor
715 /// that func would be executed on.
716 ///
717 /// Preconditions:
718 ///
719 /// - `valid() == true` (else throws FutureInvalid)
720 ///
721 /// Postconditions:
722 ///
723 /// - `valid() == false`
724 /// - `RESULT.valid() == true`
725 template <typename F>
726 SemiFuture<typename futures::detail::valueCallableResult<T, F>::value_type>
727 deferValue(F&& func) &&;
728
729 /// Defer for functions taking a T rather than a Try<T>.
730 /// Function must take a const Executor::KeepAlive<>& and a T as parameters.
731 ///
732 /// As for deferValue(F&& func) except as the first parameter to func a
733 /// KeepAlive representing the executor running the work will be provided.
734 template <typename F>
735 SemiFuture<
736 typename futures::detail::valueExecutorCallableResult<T, F>::value_type>
737 deferExValue(F&& func) &&;
738
739 /// Defer work to run on the consumer of the future.
740 /// Function must take a T as a parameter.
741 ///
742 /// As for deferValue(F&& func) but supporting function references.
743 template <typename R, typename... Args>
deferValue(R (& func)(Args...))744 auto deferValue(R (&func)(Args...)) && {
745 return std::move(*this).deferValue(&func);
746 }
747
748 /// Set an error continuation for this SemiFuture where the continuation can
749 /// be called with a known exception type and returns a `T`, `Future<T>`, or
750 /// `SemiFuture<T>`.
751 ///
752 /// Example:
753 ///
754 /// ```
755 /// makeSemiFuture()
756 /// .defer([] {
757 /// throw std::runtime_error("oh no!");
758 /// return 42;
759 /// })
760 /// .deferError(folly::tag_t<std::runtime_error>{}, [] (auto const& e) {
761 /// LOG(INFO) << "std::runtime_error: " << e.what();
762 /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1)
763 /// });
764 /// ```
765 ///
766 /// Preconditions:
767 ///
768 /// - `valid() == true` (else throws FutureInvalid)
769 ///
770 /// Postconditions:
771 ///
772 /// - `valid() == false`
773 /// - `RESULT.valid() == true`
774 template <class ExceptionType, class F>
775 SemiFuture<T> deferError(tag_t<ExceptionType>, F&& func) &&;
776
777 /// As for deferError(tag_t<ExceptionType>, F&& func) but supporting function
778 /// references.
779 template <class ExceptionType, class R, class... Args>
deferError(tag_t<ExceptionType> tag,R (& func)(Args...))780 SemiFuture<T> deferError(tag_t<ExceptionType> tag, R (&func)(Args...)) && {
781 return std::move(*this).deferError(tag, &func);
782 }
783
784 /// As for deferError(tag_t<ExceptionType>, F&& func) but makes the exception
785 /// explicit as a template argument rather than using a tag type.
786 template <class ExceptionType, class F>
deferError(F && func)787 SemiFuture<T> deferError(F&& func) && {
788 return std::move(*this).deferError(
789 tag_t<ExceptionType>{}, static_cast<F&&>(func));
790 }
791
792 /// Set an error continuation for this SemiFuture where the continuation can
793 /// be called with `exception_wrapper&&` and returns a `T`, `Future<T>`, or
794 /// `SemiFuture<T>`.
795 ///
796 /// Example:
797 ///
798 /// makeSemiFuture()
799 /// .defer([] {
800 /// throw std::runtime_error("oh no!");
801 /// return 42;
802 /// })
803 /// .deferError([] (exception_wrapper&& e) {
804 /// LOG(INFO) << e.what();
805 /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1)
806 /// });
807 ///
808 /// Preconditions:
809 ///
810 /// - `valid() == true` (else throws FutureInvalid)
811 ///
812 /// Postconditions:
813 ///
814 /// - `valid() == false`
815 /// - `RESULT.valid() == true`
816 template <class F>
817 SemiFuture<T> deferError(F&& func) &&;
818
819 /// As for deferError(tag_t<ExceptionType>, F&& func) but supporting function
820 /// references.
821 template <class R, class... Args>
deferError(R (& func)(Args...))822 SemiFuture<T> deferError(R (&func)(Args...)) && {
823 return std::move(*this).deferError(&func);
824 }
825
826 /// Convenience method for ignoring the value and creating a Future<Unit>.
827 /// Exceptions still propagate.
828 ///
829 /// Preconditions:
830 ///
831 /// - `valid() == true` (else throws FutureInvalid)
832 ///
833 /// Postconditions:
834 ///
835 /// - Calling code should act as if `valid() == false`,
836 /// i.e., as if `*this` was moved into RESULT.
837 /// - `RESULT.valid() == true`
838 SemiFuture<Unit> unit() &&;
839
840 /// If this SemiFuture completes within duration dur from now, propagate its
841 /// value. Otherwise satisfy the returned SemiFuture with a FutureTimeout
842 /// exception.
843 ///
844 /// The optional Timekeeper is as with futures::sleep().
845 ///
846 /// Preconditions:
847 ///
848 /// - `valid() == true` (else throws FutureInvalid)
849 ///
850 /// Postconditions:
851 ///
852 /// - Calling code should act as if `valid() == false`,
853 /// i.e., as if `*this` was moved into RESULT.
854 /// - `RESULT.valid() == true`
855 SemiFuture<T> within(HighResDuration dur, Timekeeper* tk = nullptr) && {
856 return std::move(*this).within(dur, FutureTimeout(), tk);
857 }
858
859 /// If this SemiFuture completes within duration dur from now, propagate its
860 /// value. Otherwise satisfy the returned SemiFuture with exception e.
861 ///
862 /// The optional Timekeeper is as with futures::sleep().
863 ///
864 /// Preconditions:
865 ///
866 /// - `valid() == true` (else throws FutureInvalid)
867 ///
868 /// Postconditions:
869 ///
870 /// - Calling code should act as if `valid() == false`,
871 /// i.e., as if `*this` was moved into RESULT.
872 /// - `RESULT.valid() == true`
873 template <class E>
874 SemiFuture<T> within(HighResDuration dur, E e, Timekeeper* tk = nullptr) &&;
875
876 /// Delay the completion of this SemiFuture for at least this duration from
877 /// now. The optional Timekeeper is as with futures::sleep().
878 ///
879 /// Preconditions:
880 ///
881 /// - `valid() == true` (else throws FutureInvalid)
882 ///
883 /// Postconditions:
884 ///
885 /// - `valid() == false`
886 /// - `RESULT.valid() == true`
887 SemiFuture<T> delayed(HighResDuration dur, Timekeeper* tk = nullptr) &&;
888
889 /// Returns a future that completes inline, as if the future had no executor.
890 /// Intended for porting legacy code without behavioral change, and for rare
891 /// cases where this is really the intended behavior.
892 /// Future is unsafe in the sense that the executor it completes on is
893 /// non-deterministic in the standard case.
894 /// For new code, or to update code that temporarily uses this, please
895 /// use via and pass a meaningful executor.
896 ///
897 /// Preconditions:
898 ///
899 /// - `valid() == true` (else throws FutureInvalid)
900 ///
901 /// Postconditions:
902 ///
903 /// - `valid() == false`
904 /// - `RESULT.valid() == true`
905 Future<T> toUnsafeFuture() &&;
906
907 #if FOLLY_HAS_COROUTINES
908
909 // Customise the co_viaIfAsync() operator so that SemiFuture<T> can be
910 // directly awaited within a folly::coro::Task coroutine.
co_viaIfAsync(folly::Executor::KeepAlive<> executor,SemiFuture<T> && future)911 friend Future<T> co_viaIfAsync(
912 folly::Executor::KeepAlive<> executor, SemiFuture<T>&& future) noexcept {
913 return std::move(future).via(std::move(executor));
914 }
915
916 #endif
917
918 private:
919 friend class Promise<T>;
920 template <class>
921 friend class futures::detail::FutureBase;
922 template <class>
923 friend class SemiFuture;
924 template <class>
925 friend class Future;
926 friend futures::detail::DeferredWrapper
927 futures::detail::stealDeferredExecutor<T>(SemiFuture<T>&);
928 friend DeferredExecutor* futures::detail::getDeferredExecutor<T>(
929 SemiFuture<T>&);
930
931 using Base::setExecutor;
932 using Base::throwIfInvalid;
933 using typename Base::Core;
934
935 template <class T2>
936 friend SemiFuture<T2> makeSemiFuture(Try<T2>);
937
SemiFuture(Core * obj)938 explicit SemiFuture(Core* obj) : Base(obj) {}
939
SemiFuture(futures::detail::EmptyConstruct)940 explicit SemiFuture(futures::detail::EmptyConstruct) noexcept
941 : Base(futures::detail::EmptyConstruct{}) {}
942
943 // Throws FutureInvalid if !this->core_
944 futures::detail::DeferredWrapper stealDeferredExecutor();
945
946 /// Blocks until the future is fulfilled, or `dur` elapses.
947 ///
948 /// Preconditions:
949 ///
950 /// - `valid() == true` (else throws FutureInvalid)
951 ///
952 /// Postconditions:
953 ///
954 /// - `valid() == true`
955 /// - `&RESULT == this`
956 /// - `isReady()` will be indeterminate - may or may not be true
957 SemiFuture<T>& wait(HighResDuration dur) &;
958
959 static void releaseDeferredExecutor(Core* core);
960 };
961
962 template <class T>
makePromiseContract()963 std::pair<Promise<T>, SemiFuture<T>> makePromiseContract() {
964 auto p = Promise<T>();
965 auto f = p.getSemiFuture();
966 return std::make_pair(std::move(p), std::move(f));
967 }
968
969 /// The interface (along with SemiFuture) for the consumer-side of a
970 /// producer/consumer pair.
971 ///
972 /// Future vs. SemiFuture:
973 ///
974 /// - The consumer-side should generally start with a SemiFuture, not a Future.
975 /// - Example, when a library creates and returns a future, it should usually
976 /// return a `SemiFuture`, not a Future.
977 /// - Reason: so the thread policy for continuations (`.thenValue`, etc.) can be
978 /// specified by the library's caller (using `.via()`).
979 /// - A SemiFuture is converted to a Future using `.via()`.
980 /// - Use `makePromiseContract()` when creating both a Promise and an associated
981 /// SemiFuture/Future.
982 ///
983 /// When practical, prefer SemiFuture/Future's nonblocking style/pattern:
984 ///
985 /// - the nonblocking style uses continuations, e.g., `.thenValue`, etc.; the
986 /// continuations are deferred until the result is available.
987 /// - the blocking style blocks until complete, e.g., `.wait()`, `.get()`, etc.
988 /// - the two styles cannot be mixed within the same future; use one or the
989 /// other.
990 ///
991 /// SemiFuture/Future also provide a back-channel so an interrupt can
992 /// be sent from consumer to producer; see SemiFuture/Future's `raise()`
993 /// and Promise's `setInterruptHandler()`.
994 ///
995 /// The consumer-side SemiFuture/Future objects should generally be accessed
996 /// via a single thread. That thread is referred to as the 'consumer thread.'
997 template <class T>
998 class Future : private futures::detail::FutureBase<T> {
999 private:
1000 using Base = futures::detail::FutureBase<T>;
1001
1002 public:
1003 /// Type of the value that the producer, when successful, produces.
1004 using typename Base::value_type;
1005
1006 /// Construct a Future from a value (perfect forwarding)
1007 ///
1008 /// Postconditions:
1009 ///
1010 /// - `valid() == true`
1011 /// - `isReady() == true`
1012 /// - `hasValue() == true`
1013 /// - `value()`, `get()`, `result()` will return the forwarded `T`
1014 template <
1015 class T2 = T,
1016 typename = typename std::enable_if<
1017 !isFuture<typename std::decay<T2>::type>::value &&
1018 !isSemiFuture<typename std::decay<T2>::type>::value &&
1019 std::is_constructible<Try<T>, T2>::value>::type>
Future(T2 && val)1020 /* implicit */ Future(T2&& val) : Base(static_cast<T2&&>(val)) {}
1021
1022 /// Construct a (logical) Future-of-void.
1023 ///
1024 /// Postconditions:
1025 ///
1026 /// - `valid() == true`
1027 /// - `isReady() == true`
1028 /// - `hasValue() == true`
1029 template <class T2 = T>
1030 /* implicit */ Future(
1031 typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr)
Base(p)1032 : Base(p) {}
1033
1034 /// Construct a Future from a `T` constructed from `args`
1035 ///
1036 /// Postconditions:
1037 ///
1038 /// - `valid() == true`
1039 /// - `isReady() == true`
1040 /// - `hasValue() == true`
1041 /// - `hasException() == false`
1042 /// - `value()`, `get()`, `result()` will return the newly constructed `T`
1043 template <
1044 class... Args,
1045 typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
1046 type = 0>
Future(in_place_t,Args &&...args)1047 explicit Future(in_place_t, Args&&... args)
1048 : Base(in_place, static_cast<Args&&>(args)...) {}
1049
1050 Future(Future<T> const&) = delete;
1051 // movable
1052 Future(Future<T>&&) noexcept;
1053
1054 // converting move
1055 template <
1056 class T2,
1057 typename std::enable_if<
1058 !std::is_same<T, typename std::decay<T2>::type>::value &&
1059 std::is_constructible<T, T2&&>::value &&
1060 std::is_convertible<T2&&, T>::value,
1061 int>::type = 0>
Future(Future<T2> && other)1062 /* implicit */ Future(Future<T2>&& other)
1063 : Future(std::move(other).thenValue(
1064 [](T2&& v) { return T(std::move(v)); })) {}
1065
1066 template <
1067 class T2,
1068 typename std::enable_if<
1069 !std::is_same<T, typename std::decay<T2>::type>::value &&
1070 std::is_constructible<T, T2&&>::value &&
1071 !std::is_convertible<T2&&, T>::value,
1072 int>::type = 0>
Future(Future<T2> && other)1073 explicit Future(Future<T2>&& other)
1074 : Future(std::move(other).thenValue(
1075 [](T2&& v) { return T(std::move(v)); })) {}
1076
1077 template <
1078 class T2,
1079 typename std::enable_if<
1080 !std::is_same<T, typename std::decay<T2>::type>::value &&
1081 std::is_constructible<T, T2&&>::value,
1082 int>::type = 0>
1083 Future& operator=(Future<T2>&& other) {
1084 return operator=(
1085 std::move(other).thenValue([](T2&& v) { return T(std::move(v)); }));
1086 }
1087
1088 using Base::cancel;
1089 using Base::hasException;
1090 using Base::hasValue;
1091 using Base::isReady;
1092 using Base::poll;
1093 using Base::raise;
1094 using Base::result;
1095 using Base::setCallback_;
1096 using Base::valid;
1097 using Base::value;
1098
1099 /// Creates/returns an invalid Future, that is, one with no shared state.
1100 ///
1101 /// Postcondition:
1102 ///
1103 /// - `RESULT.valid() == false`
1104 static Future<T> makeEmpty();
1105
1106 // not copyable
1107 Future& operator=(Future const&) = delete;
1108
1109 // movable
1110 Future& operator=(Future&&) noexcept;
1111
1112 /// Call e->drive() repeatedly until the future is fulfilled.
1113 ///
1114 /// Examples of DrivableExecutor include EventBase and ManualExecutor.
1115 ///
1116 /// Returns the fulfilled value (moved-out) or throws the fulfilled exception.
1117 T getVia(DrivableExecutor* e) &&;
1118
1119 /// Call e->drive() repeatedly until the future is fulfilled, or `dur`
1120 /// elapses.
1121 ///
1122 /// Returns the fulfilled value (moved-out), throws the fulfilled exception,
1123 /// or on timeout throws FutureTimeout.
1124 T getVia(TimedDrivableExecutor* e, HighResDuration dur) &&;
1125
1126 /// Call e->drive() repeatedly until the future is fulfilled. Examples
1127 /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
1128 /// reference to the Try of the value.
1129 Try<T> getTryVia(DrivableExecutor* e) &&;
1130
1131 /// getTryVia but will wait only until `dur` elapses. Returns the
1132 /// Try of the value (moved-out) or may throw a FutureTimeout exception.
1133 Try<T> getTryVia(TimedDrivableExecutor* e, HighResDuration dur) &&;
1134
1135 /// Unwraps the case of a Future<Future<T>> instance, and returns a simple
1136 /// Future<T> instance.
1137 ///
1138 /// Preconditions:
1139 ///
1140 /// - `valid() == true` (else throws FutureInvalid)
1141 ///
1142 /// Postconditions:
1143 ///
1144 /// - Calling code should act as if `valid() == false`,
1145 /// i.e., as if `*this` was moved into RESULT.
1146 /// - `RESULT.valid() == true`
1147 template <class F = T>
1148 typename std::
1149 enable_if<isFuture<F>::value, Future<typename isFuture<T>::Inner>>::type
1150 unwrap() &&;
1151
1152 /// Returns a Future which will call back on the other side of executor.
1153 ///
1154 /// Preconditions:
1155 ///
1156 /// - `valid() == true` (else throws FutureInvalid)
1157 ///
1158 /// Postconditions:
1159 ///
1160 /// - `valid() == false`
1161 /// - `RESULT.valid() == true`
1162 Future<T> via(Executor::KeepAlive<> executor) &&;
1163 Future<T> via(Executor::KeepAlive<> executor, int8_t priority) &&;
1164
1165 /// Returns a Future which will call back on the other side of executor.
1166 ///
1167 /// When practical, use the rvalue-qualified overload instead - it's faster.
1168 ///
1169 /// Preconditions:
1170 ///
1171 /// - `valid() == true` (else throws FutureInvalid)
1172 ///
1173 /// Postconditions:
1174 ///
1175 /// - `valid() == true`
1176 /// - `RESULT.valid() == true`
1177 /// - when `this` gets fulfilled, it automatically fulfills RESULT
1178 Future<T> via(Executor::KeepAlive<> executor) &;
1179 Future<T> via(Executor::KeepAlive<> executor, int8_t priority) &;
1180
1181 /// When this Future has completed, execute func which is a function that
1182 /// can be called with either `T&&` or `Try<T>&&`.
1183 ///
1184 /// Func shall return either another Future or a value.
1185 ///
1186 /// thenInline will run the continuation inline with the execution of the
1187 /// previous callback in the chain if the callback attached to the previous
1188 /// future that triggers execution of func runs on the same executor that func
1189 /// would be executed on.
1190 ///
1191 /// A Future for the return type of func is returned.
1192 ///
1193 /// Versions of these functions with Inline in the name will run the
1194 /// continuation inline if the executor the previous task completes on matches
1195 /// the executor the next is to be enqueued on to.
1196 ///
1197 /// Future<string> f2 = f1.thenTry([](Try<T>&&) { return string("foo"); });
1198 ///
1199 /// Preconditions:
1200 ///
1201 /// - `valid() == true` (else throws FutureInvalid)
1202 ///
1203 /// Postconditions:
1204 ///
1205 /// - Calling code should act as if `valid() == false`,
1206 /// i.e., as if `*this` was moved into RESULT.
1207 /// - `RESULT.valid() == true`
1208 template <typename F>
then(F && func)1209 Future<typename futures::detail::tryCallableResult<T, F>::value_type> then(
1210 F&& func) && {
1211 return std::move(*this).thenTry(static_cast<F&&>(func));
1212 }
1213 template <typename F>
1214 Future<typename futures::detail::tryCallableResult<T, F>::value_type>
thenInline(F && func)1215 thenInline(F&& func) && {
1216 return std::move(*this).thenTryInline(static_cast<F&&>(func));
1217 }
1218
1219 /// Variant where func is an member function
1220 ///
1221 /// struct Worker { R doWork(Try<T>); }
1222 ///
1223 /// Worker *w;
1224 /// Future<R> f2 = f1.thenTry(&Worker::doWork, w);
1225 ///
1226 /// This is just sugar for
1227 ///
1228 /// f1.thenTry(std::bind(&Worker::doWork, w));
1229 ///
1230 /// Preconditions:
1231 ///
1232 /// - `valid() == true` (else throws FutureInvalid)
1233 ///
1234 /// Postconditions:
1235 ///
1236 /// - Calling code should act as if `valid() == false`,
1237 /// i.e., as if `*this` was moved into RESULT.
1238 /// - `RESULT.valid() == true`
1239 template <typename R, typename Caller, typename... Args>
1240 Future<typename isFuture<R>::Inner> then(
1241 R (Caller::*func)(Args...), Caller* instance) &&;
1242
1243 /// Execute the callback via the given Executor. The executor doesn't stick.
1244 ///
1245 /// Contrast
1246 ///
1247 /// f.via(x).then(b).then(c)
1248 ///
1249 /// with
1250 ///
1251 /// f.then(x, b).then(c)
1252 ///
1253 /// In the former both b and c execute via x. In the latter, only b executes
1254 /// via x, and c executes via the same executor (if any) that f had.
1255 ///
1256 /// Preconditions:
1257 ///
1258 /// - `valid() == true` (else throws FutureInvalid)
1259 ///
1260 /// Postconditions:
1261 ///
1262 /// - Calling code should act as if `valid() == false`,
1263 /// i.e., as if `*this` was moved into RESULT.
1264 /// - `RESULT.valid() == true`
1265 template <class Arg>
1266 auto then(Executor::KeepAlive<> x, Arg&& arg) && = delete;
1267
1268 /// When this Future has completed, execute func which is a function that
1269 /// can be called with `Try<T>&&` (often a lambda with parameter type
1270 /// `auto&&` or `auto`).
1271 ///
1272 /// Func shall return either another Future or a value.
1273 ///
1274 /// Versions of these functions with Inline in the name will run the
1275 /// continuation inline with the execution of the previous callback in the
1276 /// chain if the callback attached to the previous future that triggers
1277 /// execution of func runs on the same executor that func would be executed
1278 /// on.
1279 ///
1280 /// A Future for the return type of func is returned.
1281 ///
1282 /// Future<string> f2 = std::move(f1).thenTry([](auto&& t) {
1283 /// ...
1284 /// return string("foo");
1285 /// });
1286 ///
1287 /// Preconditions:
1288 ///
1289 /// - `valid() == true` (else throws FutureInvalid)
1290 ///
1291 /// Postconditions:
1292 ///
1293 /// - `valid() == false`
1294 /// - `RESULT.valid() == true`
1295 template <typename F>
1296 Future<typename futures::detail::tryCallableResult<T, F>::value_type> thenTry(
1297 F&& func) &&;
1298
1299 template <typename F>
1300 Future<typename futures::detail::tryCallableResult<T, F>::value_type>
1301 thenTryInline(F&& func) &&;
1302
1303 template <typename F>
1304 Future<typename futures::detail::tryExecutorCallableResult<T, F>::value_type>
1305 thenExTry(F&& func) &&;
1306
1307 template <typename F>
1308 Future<typename futures::detail::tryExecutorCallableResult<T, F>::value_type>
1309 thenExTryInline(F&& func) &&;
1310
1311 template <typename R, typename... Args>
thenTry(R (& func)(Args...))1312 auto thenTry(R (&func)(Args...)) && {
1313 return std::move(*this).thenTry(&func);
1314 }
1315
1316 template <typename R, typename... Args>
thenTryInline(R (& func)(Args...))1317 auto thenTryInline(R (&func)(Args...)) && {
1318 return std::move(*this).thenTryInline(&func);
1319 }
1320
1321 /// When this Future has completed, execute func which is a function that
1322 /// can be called with `T&&` (often a lambda with parameter type
1323 /// `auto&&` or `auto`).
1324 ///
1325 /// Func shall return either another Future or a value.
1326 ///
1327 /// Versions of these functions with Inline in the name will run the
1328 /// continuation inline with the execution of the previous callback in the
1329 /// chain if the callback attached to the previous future that triggers
1330 /// execution of func runs on the same executor that func would be executed
1331 /// on.
1332 ///
1333 /// A Future for the return type of func is returned.
1334 ///
1335 /// Future<string> f2 = f1.thenValue([](auto&& v) {
1336 /// ...
1337 /// return string("foo");
1338 /// });
1339 ///
1340 /// Preconditions:
1341 ///
1342 /// - `valid() == true` (else throws FutureInvalid)
1343 ///
1344 /// Postconditions:
1345 ///
1346 /// - `valid() == false`
1347 /// - `RESULT.valid() == true`
1348 template <typename F>
1349 Future<typename futures::detail::valueCallableResult<T, F>::value_type>
1350 thenValue(F&& func) &&;
1351
1352 template <typename F>
1353 Future<typename futures::detail::valueCallableResult<T, F>::value_type>
1354 thenValueInline(F&& func) &&;
1355
1356 template <typename F>
1357 Future<
1358 typename futures::detail::valueExecutorCallableResult<T, F>::value_type>
1359 thenExValue(F&& func) &&;
1360
1361 template <typename F>
1362 Future<
1363 typename futures::detail::valueExecutorCallableResult<T, F>::value_type>
1364 thenExValueInline(F&& func) &&;
1365
1366 template <typename R, typename... Args>
thenValue(R (& func)(Args...))1367 auto thenValue(R (&func)(Args...)) && {
1368 return std::move(*this).thenValue(&func);
1369 }
1370
1371 template <typename R, typename... Args>
thenValueInline(R (& func)(Args...))1372 auto thenValueInline(R (&func)(Args...)) && {
1373 return std::move(*this).thenValueInline(&func);
1374 }
1375
1376 /// Set an error continuation for this Future where the continuation can
1377 /// be called with a known exception type and returns a `T`, `Future<T>`, or
1378 /// `SemiFuture<T>`.
1379 ///
1380 /// Example:
1381 ///
1382 /// makeFuture()
1383 /// .thenTry([] {
1384 /// throw std::runtime_error("oh no!");
1385 /// return 42;
1386 /// })
1387 /// .thenError(folly::tag_t<std::runtime_error>{}, [] (auto const& e) {
1388 /// LOG(INFO) << "std::runtime_error: " << e.what();
1389 /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1)
1390 /// });
1391 ///
1392 /// Preconditions:
1393 ///
1394 /// - `valid() == true` (else throws FutureInvalid)
1395 ///
1396 /// Postconditions:
1397 ///
1398 /// - `valid() == false`
1399 /// - `RESULT.valid() == true`
1400 template <class ExceptionType, class F>
1401 typename std::enable_if<
1402 isFutureOrSemiFuture<invoke_result_t<F, ExceptionType>>::value,
1403 Future<T>>::type
1404 thenError(tag_t<ExceptionType>, F&& func) &&;
1405
1406 template <class ExceptionType, class F>
1407 typename std::enable_if<
1408 !isFutureOrSemiFuture<invoke_result_t<F, ExceptionType>>::value,
1409 Future<T>>::type
1410 thenError(tag_t<ExceptionType>, F&& func) &&;
1411
1412 template <class ExceptionType, class R, class... Args>
thenError(tag_t<ExceptionType> tag,R (& func)(Args...))1413 Future<T> thenError(tag_t<ExceptionType> tag, R (&func)(Args...)) && {
1414 return std::move(*this).thenError(tag, &func);
1415 }
1416
1417 template <class ExceptionType, class F>
thenError(F && func)1418 Future<T> thenError(F&& func) && {
1419 return std::move(*this).thenError(
1420 tag_t<ExceptionType>{}, static_cast<F&&>(func));
1421 }
1422
1423 /// Set an error continuation for this Future where the continuation can
1424 /// be called with `exception_wrapper&&` and returns a `T`, `Future<T>`, or
1425 /// `SemiFuture<T>`.
1426 ///
1427 /// Example:
1428 ///
1429 /// makeFuture()
1430 /// .thenTry([] {
1431 /// throw std::runtime_error("oh no!");
1432 /// return 42;
1433 /// })
1434 /// .thenError([] (exception_wrapper&& e) {
1435 /// LOG(INFO) << e.what();
1436 /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1)
1437 /// });
1438 ///
1439 /// Preconditions:
1440 ///
1441 /// - `valid() == true` (else throws FutureInvalid)
1442 ///
1443 /// Postconditions:
1444 ///
1445 /// - `valid() == false`
1446 /// - `RESULT.valid() == true`
1447 template <class F>
1448 typename std::enable_if<
1449 isFutureOrSemiFuture<invoke_result_t<F, exception_wrapper>>::value,
1450 Future<T>>::type
1451 thenError(F&& func) &&;
1452
1453 template <class F>
1454 typename std::enable_if<
1455 !isFutureOrSemiFuture<invoke_result_t<F, exception_wrapper>>::value,
1456 Future<T>>::type
1457 thenError(F&& func) &&;
1458
1459 template <class R, class... Args>
thenError(R (& func)(Args...))1460 Future<T> thenError(R (&func)(Args...)) && {
1461 return std::move(*this).thenError(&func);
1462 }
1463
1464 /// Convenience method for ignoring the value and creating a Future<Unit>.
1465 /// Exceptions still propagate.
1466 /// This function is identical to .unit().
1467 ///
1468 /// Preconditions:
1469 ///
1470 /// - `valid() == true` (else throws FutureInvalid)
1471 ///
1472 /// Postconditions:
1473 ///
1474 /// - Calling code should act as if `valid() == false`,
1475 /// i.e., as if `*this` was moved into RESULT.
1476 /// - `RESULT.valid() == true`
1477 Future<Unit> then() &&;
1478
1479 /// Convenience method for ignoring the value and creating a Future<Unit>.
1480 /// Exceptions still propagate.
1481 /// This function is identical to parameterless .then().
1482 ///
1483 /// Preconditions:
1484 ///
1485 /// - `valid() == true` (else throws FutureInvalid)
1486 ///
1487 /// Postconditions:
1488 ///
1489 /// - Calling code should act as if `valid() == false`,
1490 /// i.e., as if `*this` was moved into RESULT.
1491 /// - `RESULT.valid() == true`
unit()1492 Future<Unit> unit() && { return std::move(*this).then(); }
1493
1494 /// Set an error continuation for this Future. The continuation should take an
1495 /// argument of the type that you want to catch, and should return a value of
1496 /// the same type as this Future, or a Future of that type (see overload
1497 /// below).
1498 ///
1499 /// Example:
1500 ///
1501 /// makeFuture()
1502 /// .thenValue([](folly::Unit&&) {
1503 /// throw std::runtime_error("oh no!");
1504 /// return 42;
1505 /// })
1506 /// .thenError([](folly::exception_wrapper&& e) {
1507 /// LOG(INFO) << "std::runtime_error: " << e.get_exception()->what();
1508 /// return -1; // or makeFuture<int>(-1)
1509 /// });
1510 ///
1511 /// Preconditions:
1512 ///
1513 /// - `valid() == true` (else throws FutureInvalid)
1514 ///
1515 /// Postconditions:
1516 ///
1517 /// - Calling code should act as if `valid() == false`,
1518 /// i.e., as if `*this` was moved into RESULT.
1519 /// - `RESULT.valid() == true`
1520 template <class F>
1521 [[deprecated(
1522 "onError loses the attached executor and is weakly typed. Please move to thenError instead.")]]
1523 typename std::enable_if<
1524 !is_invocable_v<F, exception_wrapper> &&
1525 !futures::detail::Extract<F>::ReturnsFuture::value,
1526 Future<T>>::type
1527 onError(F&& func) && = delete;
1528
1529 /// Overload of onError where the error continuation returns a Future<T>
1530 ///
1531 /// Preconditions:
1532 ///
1533 /// - `valid() == true` (else throws FutureInvalid)
1534 ///
1535 /// Postconditions:
1536 ///
1537 /// - Calling code should act as if `valid() == false`,
1538 /// i.e., as if `*this` was moved into RESULT.
1539 /// - `RESULT.valid() == true`
1540 template <class F>
1541 [[deprecated(
1542 "onError loses the attached executor and is weakly typed. Please move to thenError instead.")]]
1543 typename std::enable_if<
1544 !is_invocable_v<F, exception_wrapper> &&
1545 futures::detail::Extract<F>::ReturnsFuture::value,
1546 Future<T>>::type
1547 onError(F&& func) && = delete;
1548
1549 /// Overload of onError that takes exception_wrapper and returns Future<T>
1550 ///
1551 /// Preconditions:
1552 ///
1553 /// - `valid() == true` (else throws FutureInvalid)
1554 ///
1555 /// Postconditions:
1556 ///
1557 /// - Calling code should act as if `valid() == false`,
1558 /// i.e., as if `*this` was moved into RESULT.
1559 /// - `RESULT.valid() == true`
1560 template <class F>
1561 [[deprecated(
1562 "onError loses the attached executor and is weakly typed. Please move to thenError instead.")]]
1563 typename std::enable_if<
1564 is_invocable_v<F, exception_wrapper> &&
1565 futures::detail::Extract<F>::ReturnsFuture::value,
1566 Future<T>>::type
1567 onError(F&& func) && = delete;
1568
1569 /// Overload of onError that takes exception_wrapper and returns T
1570 ///
1571 /// Preconditions:
1572 ///
1573 /// - `valid() == true` (else throws FutureInvalid)
1574 ///
1575 /// Postconditions:
1576 ///
1577 /// - Calling code should act as if `valid() == false`,
1578 /// i.e., as if `*this` was moved into RESULT.
1579 /// - `RESULT.valid() == true`
1580 template <class F>
1581 [[deprecated(
1582 "onError loses the attached executor and is weakly typed. Please move to thenError instead.")]]
1583 typename std::enable_if<
1584 is_invocable_v<F, exception_wrapper> &&
1585 !futures::detail::Extract<F>::ReturnsFuture::value,
1586 Future<T>>::type
1587 onError(F&& func) && = delete;
1588
1589 template <class R, class... Args>
1590 Future<T> onError(R (&func)(Args...)) && = delete;
1591
1592 // clang-format off
1593 template <class F>
1594 [[deprecated(
1595 "onError loses the attached executor and is weakly typed. Please move to thenError instead.")]]
1596 Future<T> onError(F&& func) & = delete;
1597
1598 /// func is like std::function<void()> and is executed unconditionally, and
1599 /// the value/exception is passed through to the resulting Future.
1600 /// func shouldn't throw, but if it does it will be captured and propagated,
1601 /// and discard any value/exception that this Future has obtained.
1602 ///
1603 /// Preconditions:
1604 ///
1605 /// - `valid() == true` (else throws FutureInvalid)
1606 ///
1607 /// Postconditions:
1608 ///
1609 /// - Calling code should act as if `valid() == false`,
1610 /// i.e., as if `*this` was moved into RESULT.
1611 /// - `RESULT.valid() == true`
1612 template <class F>
1613 Future<T> ensure(F&& func) &&;
1614 // clang-format on
1615
1616 /// Like thenError, but for timeouts. example:
1617 ///
1618 /// Future<int> f = makeFuture<int>(42)
1619 /// .delayed(long_time)
1620 /// .onTimeout(short_time,
1621 /// [] { return -1; });
1622 ///
1623 /// or perhaps
1624 ///
1625 /// Future<int> f = makeFuture<int>(42)
1626 /// .delayed(long_time)
1627 /// .onTimeout(short_time,
1628 /// [] { return makeFuture<int>(some_exception); });
1629 ///
1630 /// Preconditions:
1631 ///
1632 /// - `valid() == true` (else throws FutureInvalid)
1633 ///
1634 /// Postconditions:
1635 ///
1636 /// - Calling code should act as if `valid() == false`,
1637 /// i.e., as if `*this` was moved into RESULT.
1638 /// - `RESULT.valid() == true`
1639 template <class F>
1640 Future<T> onTimeout(HighResDuration, F&& func, Timekeeper* = nullptr) &&;
1641
1642 /// If this Future completes within duration dur from now, propagate its
1643 /// value. Otherwise satisfy the returned SemiFuture with a FutureTimeout
1644 /// exception.
1645 ///
1646 /// The optional Timekeeper is as with futures::sleep().
1647 ///
1648 /// Preconditions:
1649 ///
1650 /// - `valid() == true` (else throws FutureInvalid)
1651 ///
1652 /// Postconditions:
1653 ///
1654 /// - Calling code should act as if `valid() == false`,
1655 /// i.e., as if `*this` was moved into RESULT.
1656 /// - `RESULT.valid() == true`
1657 Future<T> within(HighResDuration dur, Timekeeper* tk = nullptr) &&;
1658
1659 /// If this SemiFuture completes within duration dur from now, propagate its
1660 /// value. Otherwise satisfy the returned SemiFuture with exception e.
1661 ///
1662 /// The optional Timekeeper is as with futures::sleep().
1663 ///
1664 /// Preconditions:
1665 ///
1666 /// - `valid() == true` (else throws FutureInvalid)
1667 ///
1668 /// Postconditions:
1669 ///
1670 /// - Calling code should act as if `valid() == false`,
1671 /// i.e., as if `*this` was moved into RESULT.
1672 /// - `RESULT.valid() == true`
1673 template <class E>
1674 Future<T> within(
1675 HighResDuration dur, E exception, Timekeeper* tk = nullptr) &&;
1676
1677 /// Delay the completion of this Future for at least this duration from
1678 /// now. The optional Timekeeper is as with futures::sleep().
1679 ///
1680 /// Preconditions:
1681 ///
1682 /// - `valid() == true` (else throws FutureInvalid)
1683 ///
1684 /// Postconditions:
1685 ///
1686 /// - `valid() == false`
1687 /// - `RESULT.valid() == true`
1688 Future<T> delayed(HighResDuration, Timekeeper* = nullptr) &&;
1689
1690 /// Blocks until the future is fulfilled. Returns the value (moved-out), or
1691 /// throws the exception. The future must not already have a continuation.
1692 ///
1693 /// Preconditions:
1694 ///
1695 /// - `valid() == true` (else throws FutureInvalid)
1696 ///
1697 /// Postconditions:
1698 ///
1699 /// - `valid() == false`
1700 T get() &&;
1701
1702 /// Blocks until the future is fulfilled, or until `dur` elapses. Returns the
1703 /// value (moved-out), or throws the exception (which might be a FutureTimeout
1704 /// exception).
1705 ///
1706 /// Preconditions:
1707 ///
1708 /// - `valid() == true` (else throws FutureInvalid)
1709 ///
1710 /// Postconditions:
1711 ///
1712 /// - `valid() == false`
1713 T get(HighResDuration dur) &&;
1714
1715 /// Blocks until the future is fulfilled. Returns the Try of the result
1716 /// (moved-out).
1717 ///
1718 /// Preconditions:
1719 ///
1720 /// - `valid() == true` (else throws FutureInvalid)
1721 ///
1722 /// Postconditions:
1723 ///
1724 /// - `valid() == false`
1725 Try<T> getTry() &&;
1726
1727 /// Blocks until the future is fulfilled, or until `dur` elapses.
1728 /// Returns the Try of the result (moved-out), or throws FutureTimeout
1729 /// exception.
1730 ///
1731 /// Preconditions:
1732 ///
1733 /// - `valid() == true` (else throws FutureInvalid)
1734 ///
1735 /// Postconditions:
1736 ///
1737 /// - `valid() == false`
1738 Try<T> getTry(HighResDuration dur) &&;
1739
1740 /// Blocks until this Future is complete.
1741 ///
1742 /// Preconditions:
1743 ///
1744 /// - `valid() == true` (else throws FutureInvalid)
1745 ///
1746 /// Postconditions:
1747 ///
1748 /// - `valid() == true`
1749 /// - `&RESULT == this`
1750 /// - `isReady() == true`
1751 Future<T>& wait() &;
1752
1753 /// Blocks until this Future is complete.
1754 ///
1755 /// Preconditions:
1756 ///
1757 /// - `valid() == true` (else throws FutureInvalid)
1758 ///
1759 /// Postconditions:
1760 ///
1761 /// - `valid() == true` (but the calling code can trivially move-out `*this`
1762 /// by assigning or constructing the result into a distinct object).
1763 /// - `&RESULT == this`
1764 /// - `isReady() == true`
1765 Future<T>&& wait() &&;
1766
1767 /// Blocks until this Future is complete, or `dur` elapses.
1768 ///
1769 /// Preconditions:
1770 ///
1771 /// - `valid() == true` (else throws FutureInvalid)
1772 ///
1773 /// Postconditions:
1774 ///
1775 /// - `valid() == true` (so you may call `wait(...)` repeatedly)
1776 /// - `&RESULT == this`
1777 /// - `isReady()` will be indeterminate - may or may not be true
1778 Future<T>& wait(HighResDuration dur) &;
1779
1780 /// Blocks until this Future is complete or until `dur` passes.
1781 ///
1782 /// Preconditions:
1783 ///
1784 /// - `valid() == true` (else throws FutureInvalid)
1785 ///
1786 /// Postconditions:
1787 ///
1788 /// - `valid() == true` (but the calling code can trivially move-out `*this`
1789 /// by assigning or constructing the result into a distinct object).
1790 /// - `&RESULT == this`
1791 /// - `isReady()` will be indeterminate - may or may not be true
1792 Future<T>&& wait(HighResDuration dur) &&;
1793
1794 /// Call e->drive() repeatedly until the future is fulfilled. Examples
1795 /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
1796 /// reference to this Future so that you can chain calls if desired.
1797 /// value (moved-out), or throws the exception.
1798 ///
1799 /// Preconditions:
1800 ///
1801 /// - `valid() == true` (else throws FutureInvalid)
1802 ///
1803 /// Postconditions:
1804 ///
1805 /// - `valid() == true` (does not move-out `*this`)
1806 /// - `&RESULT == this`
1807 Future<T>& waitVia(DrivableExecutor* e) &;
1808
1809 /// Overload of waitVia() for rvalue Futures
1810 ///
1811 /// Preconditions:
1812 ///
1813 /// - `valid() == true` (else throws FutureInvalid)
1814 ///
1815 /// Postconditions:
1816 ///
1817 /// - `valid() == true` (but the calling code can trivially move-out `*this`
1818 /// by assigning or constructing the result into a distinct object).
1819 /// - `&RESULT == this`
1820 Future<T>&& waitVia(DrivableExecutor* e) &&;
1821
1822 /// As waitVia but may return early after dur passes.
1823 ///
1824 /// Preconditions:
1825 ///
1826 /// - `valid() == true` (else throws FutureInvalid)
1827 ///
1828 /// Postconditions:
1829 ///
1830 /// - `valid() == true` (does not move-out `*this`)
1831 /// - `&RESULT == this`
1832 Future<T>& waitVia(TimedDrivableExecutor* e, HighResDuration dur) &;
1833
1834 /// Overload of waitVia() for rvalue Futures
1835 /// As waitVia but may return early after dur passes.
1836 ///
1837 /// Preconditions:
1838 ///
1839 /// - `valid() == true` (else throws FutureInvalid)
1840 ///
1841 /// Postconditions:
1842 ///
1843 /// - `valid() == true` (but the calling code can trivially move-out `*this`
1844 /// by assigning or constructing the result into a distinct object).
1845 /// - `&RESULT == this`
1846 Future<T>&& waitVia(TimedDrivableExecutor* e, HighResDuration dur) &&;
1847
1848 /// If the value in this Future is equal to the given Future, when they have
1849 /// both completed, the value of the resulting Future<bool> will be true. It
1850 /// will be false otherwise (including when one or both Futures have an
1851 /// exception)
1852 Future<bool> willEqual(Future<T>&);
1853
1854 /// predicate behaves like std::function<bool(T const&)>
1855 /// If the predicate does not obtain with the value, the result
1856 /// is a folly::FuturePredicateDoesNotObtain exception
1857 ///
1858 /// Preconditions:
1859 ///
1860 /// - `valid() == true` (else throws FutureInvalid)
1861 ///
1862 /// Postconditions:
1863 ///
1864 /// - Calling code should act as if `valid() == false`,
1865 /// i.e., as if `*this` was moved into RESULT.
1866 /// - `RESULT.valid() == true`
1867 template <class F>
1868 Future<T> filter(F&& predicate) &&;
1869
1870 /// Like reduce, but works on a Future<std::vector<T / Try<T>>>, for example
1871 /// the result of collect or collectAll
1872 ///
1873 /// Preconditions:
1874 ///
1875 /// - `valid() == true` (else throws FutureInvalid)
1876 ///
1877 /// Postconditions:
1878 ///
1879 /// - Calling code should act as if `valid() == false`,
1880 /// i.e., as if `*this` was moved into RESULT.
1881 /// - `RESULT.valid() == true`
1882 template <class I, class F>
1883 Future<I> reduce(I&& initial, F&& func) &&;
1884
1885 /// Moves-out `*this`, creating/returning a corresponding SemiFuture.
1886 /// Result will behave like `*this` except result won't have an Executor.
1887 ///
1888 /// Postconditions:
1889 ///
1890 /// - `RESULT.valid() ==` the original value of `this->valid()`
1891 /// - RESULT will not have an Executor regardless of whether `*this` had one
semi()1892 SemiFuture<T> semi() && { return SemiFuture<T>{std::move(*this)}; }
1893
1894 #if FOLLY_HAS_COROUTINES
1895
1896 // Overload needed to customise behaviour of awaiting a Future<T>
1897 // inside a folly::coro::Task coroutine.
co_viaIfAsync(folly::Executor::KeepAlive<> executor,Future<T> && future)1898 friend Future<T> co_viaIfAsync(
1899 folly::Executor::KeepAlive<> executor, Future<T>&& future) noexcept {
1900 return std::move(future).via(std::move(executor));
1901 }
1902
1903 #endif
1904
1905 protected:
1906 friend class Promise<T>;
1907 template <class>
1908 friend class futures::detail::FutureBase;
1909 template <class>
1910 friend class Future;
1911 template <class>
1912 friend class SemiFuture;
1913 template <class>
1914 friend class FutureSplitter;
1915
1916 using Base::setExecutor;
1917 using Base::throwIfContinued;
1918 using Base::throwIfInvalid;
1919 using typename Base::Core;
1920
Future(Core * obj)1921 explicit Future(Core* obj) : Base(obj) {}
1922
Future(futures::detail::EmptyConstruct)1923 explicit Future(futures::detail::EmptyConstruct) noexcept
1924 : Base(futures::detail::EmptyConstruct{}) {}
1925
1926 template <class T2>
1927 friend Future<T2> makeFuture(Try<T2>);
1928
1929 template <class FT>
1930 friend Future<FT> futures::detail::convertFuture(
1931 SemiFuture<FT>&& sf, const Future<FT>& f);
1932
1933 using Base::detach;
1934 template <class T2>
1935 friend void futures::detachOn(
1936 folly::Executor::KeepAlive<> exec, folly::SemiFuture<T2>&& fut);
1937 };
1938
1939 /// A Timekeeper handles the details of keeping time and fulfilling delay
1940 /// promises. The returned Future<Unit> will either complete after the
1941 /// elapsed time, or in the event of some kind of exceptional error may hold
1942 /// an exception. These Futures respond to cancellation. If you use a lot of
1943 /// Delays and many of them ultimately are unneeded (as would be the case for
1944 /// Delays that are used to trigger timeouts of async operations), then you
1945 /// can and should cancel them to reclaim resources.
1946 ///
1947 /// Users will typically get one of these via Future::sleep(HighResDuration dur)
1948 /// or use them implicitly behind the scenes by passing a timeout to some Future
1949 /// operation.
1950 ///
1951 /// Although we don't formally alias Delay = Future<Unit>,
1952 /// that's an appropriate term for it. People will probably also call these
1953 /// Timeouts, and that's ok I guess, but that term is so overloaded I thought
1954 /// it made sense to introduce a cleaner term.
1955 ///
1956 /// Remember that HighResDuration is a std::chrono duration (millisecond
1957 /// resolution at the time of writing). When writing code that uses specific
1958 /// durations, prefer using the explicit std::chrono type, e.g.
1959 /// std::chrono::milliseconds over HighResDuration. This makes the code more
1960 /// legible and means you won't be unpleasantly surprised if we redefine
1961 /// HighResDuration to microseconds, or something.
1962 ///
1963 /// timekeeper.after(std::chrono::duration_cast<HighResDuration>(someNanoseconds))
1964 class Timekeeper {
1965 public:
1966 virtual ~Timekeeper() = default;
1967
1968 /// Returns a future that will complete after the given duration with the
1969 /// elapsed time. Exceptional errors can happen but they must be
1970 /// exceptional. Use the steady (monotonic) clock.
1971 ///
1972 /// The consumer thread may cancel this Future to reclaim resources.
1973 virtual SemiFuture<Unit> after(HighResDuration dur) = 0;
1974
1975 /// Unsafe version of after that returns an inline Future.
1976 /// Any work added to this future will run inline on the Timekeeper's thread.
1977 /// This can potentially cause problems with timing.
1978 ///
1979 /// Please migrate to use after + a call to via with a valid, non-inline
1980 /// executor.
afterUnsafe(HighResDuration dur)1981 Future<Unit> afterUnsafe(HighResDuration dur) {
1982 return after(dur).toUnsafeFuture();
1983 }
1984
1985 /// Returns a future that will complete at the requested time.
1986 ///
1987 /// You may cancel this SemiFuture to reclaim resources.
1988 ///
1989 /// NB This is sugar for `after(when - now)`, so while you are welcome to
1990 /// use a std::chrono::system_clock::time_point it will not track changes to
1991 /// the system clock but rather execute that many milliseconds in the future
1992 /// according to the steady clock.
1993 template <class Clock>
1994 SemiFuture<Unit> at(std::chrono::time_point<Clock> when);
1995
1996 /// Unsafe version of at that returns an inline Future.
1997 /// Any work added to this future will run inline on the Timekeeper's thread.
1998 /// This can potentially cause problems with timing.
1999 ///
2000 /// Please migrate to use at + a call to via with a valid, non-inline
2001 /// executor.
2002 template <class Clock>
atUnsafe(std::chrono::time_point<Clock> when)2003 Future<Unit> atUnsafe(std::chrono::time_point<Clock> when) {
2004 return at(when).toUnsafeFuture();
2005 }
2006 };
2007
2008 template <class T>
makePromiseContract(Executor::KeepAlive<> e)2009 std::pair<Promise<T>, Future<T>> makePromiseContract(Executor::KeepAlive<> e) {
2010 auto p = Promise<T>();
2011 auto f = p.getSemiFuture().via(std::move(e));
2012 return std::make_pair(std::move(p), std::move(f));
2013 }
2014
2015 template <class F>
makeAsyncTask(folly::Executor::KeepAlive<> ka,F && func)2016 auto makeAsyncTask(folly::Executor::KeepAlive<> ka, F&& func) {
2017 return [func = static_cast<F&&>(func),
2018 ka = std::move(ka)](auto&& param) mutable {
2019 return via(
2020 ka,
2021 [func = std::move(func),
2022 param = static_cast<decltype(param)>(param)]() mutable {
2023 return static_cast<F&&>(func)(static_cast<decltype(param)&&>(param));
2024 });
2025 };
2026 }
2027
2028 /// This namespace is for utility functions that would usually be static
2029 /// members of Future, except they don't make sense there because they don't
2030 /// depend on the template type (rather, on the type of their arguments in
2031 /// some cases). This is the least-bad naming scheme we could think of. Some
2032 /// of the functions herein have really-likely-to-collide names, like "map"
2033 /// and "sleep".
2034 namespace futures {
2035 /// Returns a Future that will complete after the specified duration. The
2036 /// HighResDuration typedef of a `std::chrono` duration type indicates the
2037 /// resolution you can expect to be meaningful (milliseconds at the time of
2038 /// writing). Normally you wouldn't need to specify a Timekeeper, we will
2039 /// use the global futures timekeeper (we run a thread whose job it is to
2040 /// keep time for futures timeouts) but we provide the option for power
2041 /// users.
2042 ///
2043 /// The Timekeeper thread will be lazily created the first time it is
2044 /// needed. If your program never uses any timeouts or other time-based
2045 /// Futures you will pay no Timekeeper thread overhead.
2046 SemiFuture<Unit> sleep(HighResDuration, Timekeeper* = nullptr);
2047 [[deprecated(
2048 "futures::sleep now returns a SemiFuture<Unit>. "
2049 "sleepUnsafe is deprecated. "
2050 "Please call futures::sleep and apply an executor with .via")]] Future<Unit>
2051 sleepUnsafe(HighResDuration, Timekeeper* = nullptr);
2052
2053 /**
2054 * Set func as the callback for each input Future and return a vector of
2055 * Futures containing the results in the input order.
2056 */
2057 template <
2058 class It,
2059 class F,
2060 class ItT = typename std::iterator_traits<It>::value_type,
2061 class Tag = std::enable_if_t<is_invocable_v<F, typename ItT::value_type&&>>,
2062 class Result = typename decltype(std::declval<ItT>().thenValue(
2063 std::declval<F>()))::value_type>
2064 std::vector<Future<Result>> mapValue(It first, It last, F func);
2065
2066 /**
2067 * Set func as the callback for each input Future and return a vector of
2068 * Futures containing the results in the input order.
2069 */
2070 template <
2071 class It,
2072 class F,
2073 class ItT = typename std::iterator_traits<It>::value_type,
2074 class Tag =
2075 std::enable_if_t<!is_invocable_v<F, typename ItT::value_type&&>>,
2076 class Result = typename decltype(std::declval<ItT>().thenTry(
2077 std::declval<F>()))::value_type>
2078 std::vector<Future<Result>> mapTry(It first, It last, F func, int = 0);
2079
2080 /**
2081 * Set func as the callback for each input Future and return a vector of
2082 * Futures containing the results in the input order and completing on
2083 * exec.
2084 */
2085 template <
2086 class It,
2087 class F,
2088 class ItT = typename std::iterator_traits<It>::value_type,
2089 class Tag = std::enable_if_t<is_invocable_v<F, typename ItT::value_type&&>>,
2090 class Result =
2091 typename decltype(std::move(std::declval<ItT>())
2092 .via(std::declval<Executor*>())
2093 .thenValue(std::declval<F>()))::value_type>
2094 std::vector<Future<Result>> mapValue(Executor& exec, It first, It last, F func);
2095
2096 /**
2097 * Set func as the callback for each input Future and return a vector of
2098 * Futures containing the results in the input order and completing on
2099 * exec.
2100 */
2101 template <
2102 class It,
2103 class F,
2104 class ItT = typename std::iterator_traits<It>::value_type,
2105 class Tag =
2106 std::enable_if_t<!is_invocable_v<F, typename ItT::value_type&&>>,
2107 class Result =
2108 typename decltype(std::move(std::declval<ItT>())
2109 .via(std::declval<Executor*>())
2110 .thenTry(std::declval<F>()))::value_type>
2111 std::vector<Future<Result>> mapTry(
2112 Executor& exec, It first, It last, F func, int = 0);
2113
2114 // Sugar for the most common case
2115 template <class Collection, class F>
2116 auto mapValue(Collection&& c, F&& func)
2117 -> decltype(mapValue(c.begin(), c.end(), func)) {
2118 return mapValue(c.begin(), c.end(), static_cast<F&&>(func));
2119 }
2120
2121 template <class Collection, class F>
2122 auto mapTry(Collection&& c, F&& func)
2123 -> decltype(mapTry(c.begin(), c.end(), func)) {
2124 return mapTry(c.begin(), c.end(), static_cast<F&&>(func));
2125 }
2126
2127 // Sugar for the most common case
2128 template <class Collection, class F>
2129 auto mapValue(Executor& exec, Collection&& c, F&& func)
2130 -> decltype(mapValue(exec, c.begin(), c.end(), func)) {
2131 return mapValue(exec, c.begin(), c.end(), static_cast<F&&>(func));
2132 }
2133
2134 template <class Collection, class F>
2135 auto mapTry(Executor& exec, Collection&& c, F&& func)
2136 -> decltype(mapTry(exec, c.begin(), c.end(), func)) {
2137 return mapTry(exec, c.begin(), c.end(), static_cast<F&&>(func));
2138 }
2139
2140 /// Carry out the computation contained in the given future if
2141 /// the predicate holds.
2142 ///
2143 /// thunk behaves like std::function<Future<T2>(void)> or
2144 /// std::function<SemiFuture<T2>(void)>
2145 template <class F>
2146 auto when(bool p, F&& thunk)
2147 -> decltype(std::declval<invoke_result_t<F>>().unit());
2148
2149 #if !defined(FOLLY_DISABLE_FUTURE_FIBERS_BATON)
2150 SemiFuture<Unit> wait(std::unique_ptr<fibers::Baton> baton);
2151 SemiFuture<Unit> wait(std::shared_ptr<fibers::Baton> baton);
2152 #endif
2153
2154 /**
2155 * Returns a lazy SemiFuture constructed by f, which also ensures that ensure is
2156 * called before completion.
2157 * f doesn't get called until the SemiFuture is activated (e.g. through a .get()
2158 * or .via() call). If f gets called, ensure is guaranteed to be called as well.
2159 */
2160 template <typename F, class Ensure>
2161 auto ensure(F&& f, Ensure&& ensure);
2162
2163 } // namespace futures
2164
2165 /**
2166 Make a completed SemiFuture by moving in a value. e.g.
2167
2168 string foo = "foo";
2169 auto f = makeSemiFuture(std::move(foo));
2170
2171 or
2172
2173 auto f = makeSemiFuture<string>("foo");
2174 */
2175 template <class T>
2176 SemiFuture<typename std::decay<T>::type> makeSemiFuture(T&& t);
2177
2178 /** Make a completed void SemiFuture. */
2179 SemiFuture<Unit> makeSemiFuture();
2180
2181 /**
2182 Make a SemiFuture by executing a function.
2183
2184 If the function returns a value of type T, makeSemiFutureWith
2185 returns a completed SemiFuture<T>, capturing the value returned
2186 by the function.
2187
2188 If the function returns a SemiFuture<T> already, makeSemiFutureWith
2189 returns just that.
2190
2191 Either way, if the function throws, a failed Future is
2192 returned that captures the exception.
2193 */
2194
2195 // makeSemiFutureWith(SemiFuture<T>()) -> SemiFuture<T>
2196 template <class F>
2197 typename std::enable_if<
2198 isFutureOrSemiFuture<invoke_result_t<F>>::value,
2199 SemiFuture<typename invoke_result_t<F>::value_type>>::type
2200 makeSemiFutureWith(F&& func);
2201
2202 // makeSemiFutureWith(T()) -> SemiFuture<T>
2203 // makeSemiFutureWith(void()) -> SemiFuture<Unit>
2204 template <class F>
2205 typename std::enable_if<
2206 !(isFutureOrSemiFuture<invoke_result_t<F>>::value),
2207 SemiFuture<lift_unit_t<invoke_result_t<F>>>>::type
2208 makeSemiFutureWith(F&& func);
2209
2210 /// Make a failed Future from an exception_ptr.
2211 /// Because the Future's type cannot be inferred you have to specify it, e.g.
2212 ///
2213 /// auto f = makeSemiFuture<string>(std::current_exception());
2214 template <class T>
2215 [[deprecated("use makeSemiFuture(exception_wrapper)")]] SemiFuture<T>
2216 makeSemiFuture(std::exception_ptr const& e);
2217
2218 /// Make a failed SemiFuture from an exception_wrapper.
2219 template <class T>
2220 SemiFuture<T> makeSemiFuture(exception_wrapper ew);
2221
2222 /** Make a SemiFuture from an exception type E that can be passed to
2223 std::make_exception_ptr(). */
2224 template <class T, class E>
2225 typename std::
2226 enable_if<std::is_base_of<std::exception, E>::value, SemiFuture<T>>::type
2227 makeSemiFuture(E const& e);
2228
2229 /** Make a Future out of a Try */
2230 template <class T>
2231 SemiFuture<T> makeSemiFuture(Try<T> t);
2232
2233 /**
2234 Make a completed Future by moving in a value. e.g.
2235
2236 string foo = "foo";
2237 auto f = makeFuture(std::move(foo));
2238
2239 or
2240
2241 auto f = makeFuture<string>("foo");
2242
2243 NOTE: This function is deprecated. Please use makeSemiFuture and pass the
2244 appropriate executor to .via on the returned SemiFuture to get a
2245 valid Future where necessary.
2246 */
2247 template <class T>
2248 Future<typename std::decay<T>::type> makeFuture(T&& t);
2249
2250 /**
2251 Make a completed void Future.
2252
2253 NOTE: This function is deprecated. Please use makeSemiFuture and pass the
2254 appropriate executor to .via on the returned SemiFuture to get a
2255 valid Future where necessary.
2256 */
2257 Future<Unit> makeFuture();
2258
2259 /**
2260 Make a Future by executing a function.
2261
2262 If the function returns a value of type T, makeFutureWith
2263 returns a completed Future<T>, capturing the value returned
2264 by the function.
2265
2266 If the function returns a Future<T> already, makeFutureWith
2267 returns just that.
2268
2269 Either way, if the function throws, a failed Future is
2270 returned that captures the exception.
2271
2272 Calling makeFutureWith(func) is equivalent to calling
2273 makeFuture().then(func).
2274
2275 NOTE: This function is deprecated. Please use makeSemiFutureWith and pass the
2276 appropriate executor to .via on the returned SemiFuture to get a
2277 valid Future where necessary.
2278 */
2279
2280 // makeFutureWith(Future<T>()) -> Future<T>
2281 template <class F>
2282 typename std::
2283 enable_if<isFuture<invoke_result_t<F>>::value, invoke_result_t<F>>::type
2284 makeFutureWith(F&& func);
2285
2286 // makeFutureWith(T()) -> Future<T>
2287 // makeFutureWith(void()) -> Future<Unit>
2288 template <class F>
2289 typename std::enable_if<
2290 !(isFuture<invoke_result_t<F>>::value),
2291 Future<lift_unit_t<invoke_result_t<F>>>>::type
2292 makeFutureWith(F&& func);
2293
2294 /// Make a failed Future from an exception_ptr.
2295 /// Because the Future's type cannot be inferred you have to specify it, e.g.
2296 ///
2297 /// auto f = makeFuture<string>(std::current_exception());
2298 template <class T>
2299 [[deprecated("use makeSemiFuture(exception_wrapper)")]] Future<T> makeFuture(
2300 std::exception_ptr const& e);
2301
2302 /// Make a failed Future from an exception_wrapper.
2303 /// NOTE: This function is deprecated. Please use makeSemiFuture and pass the
2304 /// appropriate executor to .via on the returned SemiFuture to get a
2305 /// valid Future where necessary.
2306 template <class T>
2307 Future<T> makeFuture(exception_wrapper ew);
2308
2309 /** Make a Future from an exception type E that can be passed to
2310 std::make_exception_ptr().
2311
2312 NOTE: This function is deprecated. Please use makeSemiFuture and pass the
2313 appropriate executor to .via on the returned SemiFuture to get a
2314 valid Future where necessary.
2315 */
2316 template <class T, class E>
2317 typename std::enable_if<std::is_base_of<std::exception, E>::value, Future<T>>::
2318 type
2319 makeFuture(E const& e);
2320
2321 /**
2322 Make a Future out of a Try
2323
2324 NOTE: This function is deprecated. Please use makeSemiFuture and pass the
2325 appropriate executor to .via on the returned SemiFuture to get a
2326 valid Future where necessary.
2327 */
2328 template <class T>
2329 Future<T> makeFuture(Try<T> t);
2330
2331 /*
2332 * Return a new Future that will call back on the given Executor.
2333 * This is just syntactic sugar for makeFuture().via(executor)
2334 *
2335 * @param executor the Executor to call back on
2336 * @param priority optionally, the priority to add with. Defaults to 0 which
2337 * represents medium priority.
2338 *
2339 * @returns a void Future that will call back on the given executor
2340 */
2341 inline Future<Unit> via(Executor::KeepAlive<> executor);
2342 inline Future<Unit> via(Executor::KeepAlive<> executor, int8_t priority);
2343
2344 /// Execute a function via the given executor and return a future.
2345 /// This is semantically equivalent to via(executor).then(func), but
2346 /// easier to read and slightly more efficient.
2347 template <class Func>
2348 auto via(Executor::KeepAlive<>, Func&& func) -> Future<
2349 typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner>;
2350
2351 /** When all the input Futures complete, the returned Future will complete.
2352 Errors do not cause early termination; this Future will always succeed
2353 after all its Futures have finished (whether successfully or with an
2354 error).
2355
2356 The Futures are moved in, so your copies are invalid. If you need to
2357 chain further from these Futures, use the variant with an output iterator.
2358
2359 This function is thread-safe for Futures running on different threads. But
2360 if you are doing anything non-trivial after, you will probably want to
2361 follow with `via(executor)` because it will complete in whichever thread the
2362 last Future completes in.
2363
2364 The return type for Future<T> input is a SemiFuture<std::vector<Try<T>>>
2365 for collectX.
2366
2367 collectXUnsafe returns an inline Future that erases the executor from the
2368 incoming Futures/SemiFutures. collectXUnsafe should be phased out and
2369 replaced with collectX(...).via(e) where e is a valid non-inline executor.
2370 */
2371 // Unsafe variant, see above comment for details
2372 template <class InputIterator>
2373 Future<std::vector<
2374 Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
2375 collectAllUnsafe(InputIterator first, InputIterator last);
2376
2377 // Unsafe variant sugar, see above comment for details
2378 template <class Collection>
2379 auto collectAllUnsafe(Collection&& c)
2380 -> decltype(collectAllUnsafe(c.begin(), c.end())) {
2381 return collectAllUnsafe(c.begin(), c.end());
2382 }
2383
2384 template <class InputIterator>
2385 SemiFuture<std::vector<
2386 Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
2387 collectAll(InputIterator first, InputIterator last);
2388
2389 template <class Collection>
2390 auto collectAll(Collection&& c) -> decltype(collectAll(c.begin(), c.end())) {
2391 return collectAll(c.begin(), c.end());
2392 }
2393
2394 // Unsafe variant of collectAll, see comment above for details. Returns
2395 // a Future<std::tuple<Try<T1>, Try<T2>, ...>> on the Inline executor.
2396 template <typename... Fs>
2397 Future<std::tuple<Try<typename remove_cvref_t<Fs>::value_type>...>>
2398 collectAllUnsafe(Fs&&... fs);
2399
2400 /// This version takes a varying number of Futures instead of an iterator.
2401 /// The return type for (Future<T1>, Future<T2>, ...) input
2402 /// is a SemiFuture<std::tuple<Try<T1>, Try<T2>, ...>>.
2403 /// The Futures are moved in, so your copies are invalid.
2404 template <typename... Fs>
2405 SemiFuture<std::tuple<Try<typename remove_cvref_t<Fs>::value_type>...>>
2406 collectAll(Fs&&... fs);
2407
2408 /// Like collectAll, but will short circuit on the first exception. Thus, the
2409 /// type of the returned SemiFuture is std::vector<T> instead of
2410 /// std::vector<Try<T>>
2411 template <class InputIterator>
2412 SemiFuture<std::vector<
2413 typename std::iterator_traits<InputIterator>::value_type::value_type>>
2414 collect(InputIterator first, InputIterator last);
2415
2416 /// Sugar for the most common case
2417 template <class Collection>
2418 auto collect(Collection&& c) -> decltype(collect(c.begin(), c.end())) {
2419 return collect(c.begin(), c.end());
2420 }
2421
2422 // Unsafe variant of collect. Returns a Future<std::vector<T>> that
2423 // completes inline.
2424 template <class InputIterator>
2425 Future<std::vector<
2426 typename std::iterator_traits<InputIterator>::value_type::value_type>>
2427 collectUnsafe(InputIterator first, InputIterator last);
2428
2429 /// Sugar for the most common unsafe case. Returns a Future<std::vector<T>>
2430 // that completes inline.
2431 template <class Collection>
2432 auto collectUnsafe(Collection&& c)
2433 -> decltype(collectUnsafe(c.begin(), c.end())) {
2434 return collectUnsafe(c.begin(), c.end());
2435 }
2436
2437 /// Like collectAll, but will short circuit on the first exception. Thus, the
2438 /// type of the returned SemiFuture is std::tuple<T1, T2, ...> instead of
2439 /// std::tuple<Try<T1>, Try<T2>, ...>
2440 template <typename... Fs>
2441 SemiFuture<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collect(
2442 Fs&&... fs);
2443
2444 /** The result is a pair of the index of the first Future to complete and
2445 the Try. If multiple Futures complete at the same time (or are already
2446 complete when passed in), the "winner" is chosen non-deterministically.
2447
2448 This function is thread-safe for Futures running on different threads.
2449 */
2450 template <class InputIterator>
2451 SemiFuture<std::pair<
2452 size_t,
2453 Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
2454 collectAny(InputIterator first, InputIterator last);
2455
2456 /// Sugar for the most common case
2457 template <class Collection>
2458 auto collectAny(Collection&& c) -> decltype(collectAny(c.begin(), c.end())) {
2459 return collectAny(c.begin(), c.end());
2460 }
2461
2462 /** Similar to collectAny, collectAnyWithoutException return the first Future to
2463 * complete without exceptions. If none of the future complete without
2464 * exceptions, the last exception will be returned as a result.
2465 */
2466 template <class InputIterator>
2467 SemiFuture<std::pair<
2468 size_t,
2469 typename std::iterator_traits<InputIterator>::value_type::value_type>>
2470 collectAnyWithoutException(InputIterator first, InputIterator last);
2471
2472 /// Sugar for the most common case
2473 template <class Collection>
2474 auto collectAnyWithoutException(Collection&& c)
2475 -> decltype(collectAnyWithoutException(c.begin(), c.end())) {
2476 return collectAnyWithoutException(c.begin(), c.end());
2477 }
2478
2479 /** when n Futures have completed, the Future completes with a vector of
2480 the index and Try of those n Futures (the indices refer to the original
2481 order, but the result vector will be in an arbitrary order)
2482
2483 Not thread safe.
2484 */
2485 template <class InputIterator>
2486 SemiFuture<std::vector<std::pair<
2487 size_t,
2488 Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
2489 collectN(InputIterator first, InputIterator last, size_t n);
2490
2491 /// Sugar for the most common case
2492 template <class Collection>
2493 auto collectN(Collection&& c, size_t n)
2494 -> decltype(collectN(c.begin(), c.end(), n)) {
2495 return collectN(c.begin(), c.end(), n);
2496 }
2497
2498 /** window creates up to n Futures using the values
2499 in the collection, and then another Future for each Future
2500 that completes
2501
2502 this is basically a sliding window of Futures of size n
2503
2504 func must return a Future for each value in input
2505 */
2506 template <
2507 class Collection,
2508 class F,
2509 class ItT = typename std::iterator_traits<
2510 typename Collection::iterator>::value_type,
2511 class Result = typename invoke_result_t<F, ItT&&>::value_type>
2512 std::vector<Future<Result>> window(Collection input, F func, size_t n);
2513
2514 template <
2515 class Collection,
2516 class F,
2517 class ItT = typename std::iterator_traits<
2518 typename Collection::iterator>::value_type,
2519 class Result = typename invoke_result_t<F, ItT&&>::value_type>
2520 std::vector<Future<Result>> window(
2521 Executor::KeepAlive<> executor, Collection input, F func, size_t n);
2522
2523 template <typename F, typename T, typename ItT>
2524 using MaybeTryArg = typename std::
2525 conditional<is_invocable_v<F, T&&, Try<ItT>&&>, Try<ItT>, ItT>::type;
2526
2527 /** repeatedly calls func on every result, e.g.
2528 reduce(reduce(reduce(T initial, result of first), result of second), ...)
2529
2530 The type of the final result is a Future of the type of the initial value.
2531
2532 Func can either return a T, or a Future<T>
2533
2534 func is called in order of the input, see unorderedReduce if that is not
2535 a requirement
2536 */
2537 template <class It, class T, class F>
2538 Future<T> reduce(It first, It last, T&& initial, F&& func);
2539
2540 /// Sugar for the most common case
2541 template <class Collection, class T, class F>
2542 auto reduce(Collection&& c, T&& initial, F&& func) -> decltype(folly::reduce(
2543 c.begin(), c.end(), static_cast<T&&>(initial), static_cast<F&&>(func))) {
2544 return folly::reduce(
2545 c.begin(), c.end(), static_cast<T&&>(initial), static_cast<F&&>(func));
2546 }
2547
2548 /** like reduce, but calls func on finished futures as they complete
2549 does NOT keep the order of the input
2550 */
2551 template <class It, class T, class F>
2552 Future<T> unorderedReduce(It first, It last, T initial, F func);
2553
2554 /// Sugar for the most common case
2555 template <class Collection, class T, class F>
2556 auto unorderedReduce(Collection&& c, T&& initial, F&& func)
2557 -> decltype(folly::unorderedReduce(
2558 c.begin(),
2559 c.end(),
2560 static_cast<T&&>(initial),
2561 static_cast<F&&>(func))) {
2562 return folly::unorderedReduce(
2563 c.begin(), c.end(), static_cast<T&&>(initial), static_cast<F&&>(func));
2564 }
2565
2566 /// Carry out the computation contained in the given future if
2567 /// while the predicate continues to hold.
2568 ///
2569 /// if thunk behaves like std::function<Future<T2>(void)>
2570 /// returns Future<Unit>
2571 /// if thunk behaves like std::function<SemiFuture<T2>(void)>
2572 /// returns SemiFuture<Unit>
2573 /// predicate behaves like std::function<bool(void)>
2574 template <class P, class F>
2575 typename std::enable_if<isFuture<invoke_result_t<F>>::value, Future<Unit>>::type
2576 whileDo(P&& predicate, F&& thunk);
2577 template <class P, class F>
2578 typename std::
2579 enable_if<isSemiFuture<invoke_result_t<F>>::value, SemiFuture<Unit>>::type
2580 whileDo(P&& predicate, F&& thunk);
2581
2582 /// Repeat the given future (i.e., the computation it contains) n times.
2583 ///
2584 /// thunk behaves like
2585 /// std::function<Future<T2>(void)>
2586 /// or
2587 /// std::function<SemiFuture<T2>(void)>
2588 template <class F>
2589 auto times(int n, F&& thunk);
2590 } // namespace folly
2591
2592 #if FOLLY_HAS_COROUTINES
2593
2594 namespace folly {
2595 namespace detail {
2596
2597 template <typename T>
2598 class FutureAwaiter {
2599 public:
FutureAwaiter(folly::Future<T> && future)2600 explicit FutureAwaiter(folly::Future<T>&& future) noexcept
2601 : future_(std::move(future)) {}
2602
await_ready()2603 bool await_ready() {
2604 if (future_.isReady()) {
2605 result_ = std::move(future_.result());
2606 return true;
2607 }
2608 return false;
2609 }
2610
await_resume()2611 T await_resume() { return std::move(result_).value(); }
2612
await_resume_try()2613 Try<drop_unit_t<T>> await_resume_try() {
2614 return static_cast<Try<drop_unit_t<T>>>(std::move(result_));
2615 }
2616
await_suspend(coro::coroutine_handle<> h)2617 FOLLY_CORO_AWAIT_SUSPEND_NONTRIVIAL_ATTRIBUTES void await_suspend(
2618 coro::coroutine_handle<> h) {
2619 // FutureAwaiter may get destroyed as soon as the callback is executed.
2620 // Make sure the future object doesn't get destroyed until setCallback_
2621 // returns.
2622 auto future = std::move(future_);
2623 future.setCallback_(
2624 [this, h](Executor::KeepAlive<>&&, Try<T>&& result) mutable {
2625 result_ = std::move(result);
2626 h.resume();
2627 });
2628 }
2629
2630 private:
2631 folly::Future<T> future_;
2632 folly::Try<T> result_;
2633 };
2634
2635 } // namespace detail
2636
2637 template <typename T>
2638 inline detail::FutureAwaiter<T>
co_await(Future<T> && future)2639 /* implicit */ operator co_await(Future<T>&& future) noexcept {
2640 return detail::FutureAwaiter<T>(std::move(future));
2641 }
2642
2643 } // namespace folly
2644 #endif
2645
2646 #include <folly/futures/Future-inl.h>
2647