1 | /* |
2 | * Copyright 2014-present Facebook, Inc. |
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 | #pragma once |
17 | |
18 | #include <algorithm> |
19 | #include <exception> |
20 | #include <functional> |
21 | #include <memory> |
22 | #include <type_traits> |
23 | #include <vector> |
24 | |
25 | #include <folly/Optional.h> |
26 | #include <folly/Portability.h> |
27 | #include <folly/ScopeGuard.h> |
28 | #include <folly/Try.h> |
29 | #include <folly/Unit.h> |
30 | #include <folly/Utility.h> |
31 | #include <folly/executors/DrivableExecutor.h> |
32 | #include <folly/executors/TimedDrivableExecutor.h> |
33 | #include <folly/functional/Invoke.h> |
34 | #include <folly/futures/Promise.h> |
35 | #include <folly/futures/detail/Types.h> |
36 | #include <folly/lang/Exception.h> |
37 | |
38 | #if FOLLY_HAS_COROUTINES |
39 | #include <folly/experimental/coro/Traits.h> |
40 | #include <experimental/coroutine> |
41 | #endif |
42 | |
43 | // boring predeclarations and details |
44 | #include <folly/futures/Future-pre.h> |
45 | |
46 | // not-boring helpers, e.g. all in folly::futures, makeFuture variants, etc. |
47 | // Needs to be included after Future-pre.h and before Future-inl.h |
48 | #include <folly/futures/helpers.h> |
49 | |
50 | namespace folly { |
51 | |
52 | class FOLLY_EXPORT FutureException : public std::logic_error { |
53 | public: |
54 | using std::logic_error::logic_error; |
55 | }; |
56 | |
57 | class FOLLY_EXPORT FutureInvalid : public FutureException { |
58 | public: |
59 | FutureInvalid() : FutureException("Future invalid" ) {} |
60 | }; |
61 | |
62 | /// At most one continuation may be attached to any given Future. |
63 | /// |
64 | /// If a continuation is attached to a future to which another continuation has |
65 | /// already been attached, then an instance of FutureAlreadyContinued will be |
66 | /// thrown instead. |
67 | class FOLLY_EXPORT FutureAlreadyContinued : public FutureException { |
68 | public: |
69 | FutureAlreadyContinued() : FutureException("Future already continued" ) {} |
70 | }; |
71 | |
72 | class FOLLY_EXPORT FutureNotReady : public FutureException { |
73 | public: |
74 | FutureNotReady() : FutureException("Future not ready" ) {} |
75 | }; |
76 | |
77 | class FOLLY_EXPORT FutureCancellation : public FutureException { |
78 | public: |
79 | FutureCancellation() : FutureException("Future was cancelled" ) {} |
80 | }; |
81 | |
82 | class FOLLY_EXPORT FutureTimeout : public FutureException { |
83 | public: |
84 | FutureTimeout() : FutureException("Timed out" ) {} |
85 | }; |
86 | |
87 | class FOLLY_EXPORT FuturePredicateDoesNotObtain : public FutureException { |
88 | public: |
89 | FuturePredicateDoesNotObtain() |
90 | : FutureException("Predicate does not obtain" ) {} |
91 | }; |
92 | |
93 | class FOLLY_EXPORT FutureNoTimekeeper : public FutureException { |
94 | public: |
95 | FutureNoTimekeeper() : FutureException("No timekeeper available" ) {} |
96 | }; |
97 | |
98 | class FOLLY_EXPORT FutureNoExecutor : public FutureException { |
99 | public: |
100 | FutureNoExecutor() : FutureException("No executor provided to via" ) {} |
101 | }; |
102 | |
103 | template <class T> |
104 | class Future; |
105 | |
106 | template <class T> |
107 | class SemiFuture; |
108 | |
109 | template <class T> |
110 | class FutureSplitter; |
111 | |
112 | namespace futures { |
113 | namespace detail { |
114 | template <class T> |
115 | class FutureBase { |
116 | public: |
117 | typedef T value_type; |
118 | |
119 | /// Construct from a value (perfect forwarding) |
120 | /// |
121 | /// Postconditions: |
122 | /// |
123 | /// - `valid() == true` |
124 | /// - `isReady() == true` |
125 | /// - `hasValue() == true` |
126 | template < |
127 | class T2 = T, |
128 | typename = typename std::enable_if< |
129 | !isFuture<typename std::decay<T2>::type>::value && |
130 | !isSemiFuture<typename std::decay<T2>::type>::value>::type> |
131 | /* implicit */ FutureBase(T2&& val); |
132 | |
133 | /// Construct a (logical) FutureBase-of-void. |
134 | /// |
135 | /// Postconditions: |
136 | /// |
137 | /// - `valid() == true` |
138 | /// - `isReady() == true` |
139 | /// - `hasValue() == true` |
140 | template <class T2 = T> |
141 | /* implicit */ FutureBase( |
142 | typename std::enable_if<std::is_same<Unit, T2>::value>::type*); |
143 | |
144 | template < |
145 | class... Args, |
146 | typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: |
147 | type = 0> |
148 | explicit FutureBase(in_place_t, Args&&... args); |
149 | |
150 | FutureBase(FutureBase<T> const&) = delete; |
151 | FutureBase(SemiFuture<T>&&) noexcept; |
152 | FutureBase(Future<T>&&) noexcept; |
153 | |
154 | // not copyable |
155 | FutureBase(Future<T> const&) = delete; |
156 | FutureBase(SemiFuture<T> const&) = delete; |
157 | |
158 | ~FutureBase(); |
159 | |
160 | /// true if this has a shared state; |
161 | /// false if this has been either moved-out or created without a shared state. |
162 | bool valid() const noexcept { |
163 | return core_ != nullptr; |
164 | } |
165 | |
166 | /// Returns a reference to the result value if it is ready, with a reference |
167 | /// category and const-qualification like those of the future. |
168 | /// |
169 | /// Does not `wait()`; see `get()` for that. |
170 | /// |
171 | /// Preconditions: |
172 | /// |
173 | /// - `valid() == true` (else throws FutureInvalid) |
174 | /// - `isReady() == true` (else throws FutureNotReady) |
175 | /// |
176 | /// Postconditions: |
177 | /// |
178 | /// - If an exception has been captured (i.e., if `hasException() == true`), |
179 | /// throws that exception. |
180 | /// - This call does not mutate the future's value. |
181 | /// - However calling code may mutate that value (including moving it out by |
182 | /// move-constructing or move-assigning another value from it), for |
183 | /// example, via the `&` or the `&&` overloads or via casts. |
184 | T& value() &; |
185 | T const& value() const&; |
186 | T&& value() &&; |
187 | T const&& value() const&&; |
188 | |
189 | /// Returns a reference to the result's Try if it is ready, with a reference |
190 | /// category and const-qualification like those of the future. |
191 | /// |
192 | /// Does not `wait()`; see `get()` for that. |
193 | /// |
194 | /// Preconditions: |
195 | /// |
196 | /// - `valid() == true` (else throws FutureInvalid) |
197 | /// - `isReady() == true` (else throws FutureNotReady) |
198 | /// |
199 | /// Postconditions: |
200 | /// |
201 | /// - This call does not mutate the future's result. |
202 | /// - However calling code may mutate that result (including moving it out by |
203 | /// move-constructing or move-assigning another result from it), for |
204 | /// example, via the `&` or the `&&` overloads or via casts. |
205 | Try<T>& result() &; |
206 | Try<T> const& result() const&; |
207 | Try<T>&& result() &&; |
208 | Try<T> const&& result() const&&; |
209 | |
210 | /// True when the result (or exception) is ready; see value(), result(), etc. |
211 | /// |
212 | /// Preconditions: |
213 | /// |
214 | /// - `valid() == true` (else throws FutureInvalid) |
215 | bool isReady() const; |
216 | |
217 | /// True if the result is a value (not an exception) on a future for which |
218 | /// isReady returns true. |
219 | /// |
220 | /// Equivalent to result().hasValue() |
221 | /// |
222 | /// Preconditions: |
223 | /// |
224 | /// - `valid() == true` (else throws FutureInvalid) |
225 | /// - `isReady() == true` (else throws FutureNotReady) |
226 | bool hasValue() const; |
227 | |
228 | /// True if the result is an exception (not a value) on a future for which |
229 | /// isReady returns true. |
230 | /// |
231 | /// Equivalent to result().hasException() |
232 | /// |
233 | /// Preconditions: |
234 | /// |
235 | /// - `valid() == true` (else throws FutureInvalid) |
236 | /// - `isReady() == true` (else throws FutureNotReady) |
237 | bool hasException() const; |
238 | |
239 | /// Returns either an Optional holding the result or an empty Optional |
240 | /// depending on whether or not (respectively) the promise has been |
241 | /// fulfilled (i.e., `isReady() == true`). |
242 | /// |
243 | /// Preconditions: |
244 | /// |
245 | /// - `valid() == true` (else throws FutureInvalid) |
246 | /// |
247 | /// Postconditions: |
248 | /// |
249 | /// - `valid() == true` (note however that this moves-out the result when |
250 | /// it returns a populated `Try<T>`, which effects any subsequent use of |
251 | /// that result, e.g., `poll()`, `result()`, `value()`, `get()`, etc.) |
252 | Optional<Try<T>> poll(); |
253 | |
254 | /// This is not the method you're looking for. |
255 | /// |
256 | /// This needs to be public because it's used by make* and when*, and it's |
257 | /// not worth listing all those and their fancy template signatures as |
258 | /// friends. But it's not for public consumption. |
259 | template <class F> |
260 | void setCallback_(F&& func); |
261 | |
262 | template <class F> |
263 | void setCallback_(F&& func, std::shared_ptr<folly::RequestContext> context); |
264 | |
265 | /// Provides a threadsafe back-channel so the consumer's thread can send an |
266 | /// interrupt-object to the producer's thread. |
267 | /// |
268 | /// If the promise-holder registers an interrupt-handler and consumer thread |
269 | /// raises an interrupt early enough (details below), the promise-holder |
270 | /// will typically halt its work, fulfilling the future with an exception |
271 | /// or some special non-exception value. |
272 | /// |
273 | /// However this interrupt request is voluntary, asynchronous, & advisory: |
274 | /// |
275 | /// - Voluntary: the producer will see the interrupt only if the producer uses |
276 | /// a `Promise` object and registers an interrupt-handler; |
277 | /// see `Promise::setInterruptHandler()`. |
278 | /// - Asynchronous: the producer will see the interrupt only if `raise()` is |
279 | /// called before (or possibly shortly after) the producer is done producing |
280 | /// its result, which is asynchronous with respect to the call to `raise()`. |
281 | /// - Advisory: the producer's interrupt-handler can do whatever it wants, |
282 | /// including ignore the interrupt or perform some action other than halting |
283 | /// its producer-work. |
284 | /// |
285 | /// Guidelines: |
286 | /// |
287 | /// - It is ideal if the promise-holder can both halt its work and fulfill the |
288 | /// promise early, typically with the same exception that was delivered to |
289 | /// the promise-holder in the form of an interrupt. |
290 | /// - If the promise-holder does not do this, and if it holds the promise |
291 | /// alive for a long time, then the whole continuation chain will not be |
292 | /// invoked and the whole future chain will be kept alive for that long time |
293 | /// as well. |
294 | /// - It is also ideal if the promise-holder can invalidate the promise. |
295 | /// - The promise-holder must also track whether it has set a result in the |
296 | /// interrupt handler so that it does not attempt to do so outside the |
297 | /// interrupt handler, and must track whether it has set a result in its |
298 | /// normal flow so that it does not attempt to do so in the interrupt |
299 | /// handler, since setting a result twice is an error. Because the interrupt |
300 | /// handler can be invoked in some other thread, this tracking may have to |
301 | /// be done with some form of concurrency control. |
302 | /// |
303 | /// Preconditions: |
304 | /// |
305 | /// - `valid() == true` (else throws FutureInvalid) |
306 | /// |
307 | /// Postconditions: |
308 | /// |
309 | /// - has no visible effect if `raise()` was previously called on `this` or |
310 | /// any other Future/SemiFuture that uses the same shared state as `this`. |
311 | /// - has no visible effect if the producer never (either in the past or in |
312 | /// the future) registers an interrupt-handler. |
313 | /// - has no visible effect if the producer fulfills its promise (sets the |
314 | /// result) before (or possibly also shortly after) receiving the interrupt. |
315 | /// - otherwise the promise-holder's interrupt-handler is called, passing the |
316 | /// exception (within an `exception_wrapper`). |
317 | /// |
318 | /// The specific thread used to invoke the producer's interrupt-handler (if |
319 | /// it is called at all) depends on timing: |
320 | /// |
321 | /// - if the interrupt-handler is registered prior to `raise()` (or possibly |
322 | /// concurrently within the call to `raise()`), the interrupt-handler will |
323 | /// be executed using this current thread within the call to `raise()`. |
324 | /// - if the interrupt-handler is registered after `raise()` (and possibly |
325 | /// concurrently within the call to `raise()`), the interrupt-handler will |
326 | /// be executed using the producer's thread within the call to |
327 | /// `Promise::setInterruptHandler()`. |
328 | /// |
329 | /// Synchronizes between `raise()` (in the consumer's thread) |
330 | /// and `Promise::setInterruptHandler()` (in the producer's thread). |
331 | void raise(exception_wrapper interrupt); |
332 | |
333 | /// Raises the specified exception-interrupt. |
334 | /// See `raise(exception_wrapper)` for details. |
335 | template <class E> |
336 | void raise(E&& exception) { |
337 | raise(make_exception_wrapper<typename std::remove_reference<E>::type>( |
338 | std::forward<E>(exception))); |
339 | } |
340 | |
341 | /// Raises a FutureCancellation interrupt. |
342 | /// See `raise(exception_wrapper)` for details. |
343 | void cancel() { |
344 | raise(FutureCancellation()); |
345 | } |
346 | |
347 | // Returns this future's executor priority. |
348 | int8_t getPriority() const { |
349 | return getCore().getPriority(); |
350 | } |
351 | |
352 | protected: |
353 | friend class Promise<T>; |
354 | template <class> |
355 | friend class SemiFuture; |
356 | template <class> |
357 | friend class Future; |
358 | |
359 | using Core = futures::detail::Core<T>; |
360 | |
361 | // Throws FutureInvalid if there is no shared state object; else returns it |
362 | // by ref. |
363 | // |
364 | // Implementation methods should usually use this instead of `this->core_`. |
365 | // The latter should be used only when you need the possibly-null pointer. |
366 | Core& getCore() { |
367 | return getCoreImpl(*this); |
368 | } |
369 | Core const& getCore() const { |
370 | return getCoreImpl(*this); |
371 | } |
372 | |
373 | template <typename Self> |
374 | static decltype(auto) getCoreImpl(Self& self) { |
375 | if (!self.core_) { |
376 | throw_exception<FutureInvalid>(); |
377 | } |
378 | return *self.core_; |
379 | } |
380 | |
381 | Try<T>& getCoreTryChecked() { |
382 | return getCoreTryChecked(*this); |
383 | } |
384 | Try<T> const& getCoreTryChecked() const { |
385 | return getCoreTryChecked(*this); |
386 | } |
387 | |
388 | template <typename Self> |
389 | static decltype(auto) getCoreTryChecked(Self& self) { |
390 | auto& core = self.getCore(); |
391 | if (!core.hasResult()) { |
392 | throw_exception<FutureNotReady>(); |
393 | } |
394 | return core.getTry(); |
395 | } |
396 | |
397 | // shared core state object |
398 | // usually you should use `getCore()` instead of directly accessing `core_`. |
399 | Core* core_; |
400 | |
401 | explicit FutureBase(Core* obj) : core_(obj) {} |
402 | |
403 | explicit FutureBase(futures::detail::EmptyConstruct) noexcept; |
404 | |
405 | void detach(); |
406 | |
407 | void throwIfInvalid() const; |
408 | void throwIfContinued() const; |
409 | |
410 | void assign(FutureBase<T>&& other) noexcept; |
411 | |
412 | Executor* getExecutor() const { |
413 | return getCore().getExecutor(); |
414 | } |
415 | |
416 | // Sets the Executor within the Core state object of `this`. |
417 | // Must be called either before attaching a callback or after the callback |
418 | // has already been invoked, but not concurrently with anything which might |
419 | // trigger invocation of the callback. |
420 | void setExecutor(Executor* x, int8_t priority = Executor::MID_PRI) { |
421 | getCore().setExecutor(x, priority); |
422 | } |
423 | |
424 | void setExecutor( |
425 | Executor::KeepAlive<> x, |
426 | int8_t priority = Executor::MID_PRI) { |
427 | getCore().setExecutor(std::move(x), priority); |
428 | } |
429 | |
430 | // Variant: returns a value |
431 | // e.g. f.thenTry([](Try<T> t){ return t.value(); }); |
432 | template <typename F, typename R> |
433 | typename std::enable_if<!R::ReturnsFuture::value, typename R::Return>::type |
434 | thenImplementation(F&& func, R); |
435 | |
436 | // Variant: returns a Future |
437 | // e.g. f.thenTry([](Try<T> t){ return makeFuture<T>(t); }); |
438 | template <typename F, typename R> |
439 | typename std::enable_if<R::ReturnsFuture::value, typename R::Return>::type |
440 | thenImplementation(F&& func, R); |
441 | |
442 | template <typename E> |
443 | SemiFuture<T> withinImplementation(Duration dur, E e, Timekeeper* tk) &&; |
444 | }; |
445 | template <class T> |
446 | void convertFuture(SemiFuture<T>&& sf, Future<T>& f); |
447 | |
448 | class DeferredExecutor; |
449 | |
450 | template <typename T> |
451 | DeferredExecutor* getDeferredExecutor(SemiFuture<T>& future); |
452 | |
453 | template <typename T> |
454 | folly::Executor::KeepAlive<DeferredExecutor> stealDeferredExecutor( |
455 | SemiFuture<T>& future); |
456 | } // namespace detail |
457 | } // namespace futures |
458 | |
459 | /// The interface (along with Future) for the consumer-side of a |
460 | /// producer/consumer pair. |
461 | /// |
462 | /// Future vs. SemiFuture: |
463 | /// |
464 | /// - The consumer-side should generally start with a SemiFuture, not a Future. |
465 | /// - Example, when a library creates and returns a future, it should usually |
466 | /// return a `SemiFuture`, not a Future. |
467 | /// - Reason: so the thread policy for continuations (`.thenValue`, etc.) can be |
468 | /// specified by the library's caller (using `.via()`). |
469 | /// - A SemiFuture is converted to a Future using `.via()`. |
470 | /// - Use `makePromiseContract()` when creating both a Promise and an associated |
471 | /// SemiFuture/Future. |
472 | /// |
473 | /// When practical, prefer SemiFuture/Future's nonblocking style/pattern: |
474 | /// |
475 | /// - the nonblocking style uses continuations, e.g., `.thenValue`, etc.; the |
476 | /// continuations are deferred until the result is available. |
477 | /// - the blocking style blocks until complete, e.g., `.wait()`, `.get()`, etc. |
478 | /// - the two styles cannot be mixed within the same future; use one or the |
479 | /// other. |
480 | /// |
481 | /// SemiFuture/Future also provide a back-channel so an interrupt can |
482 | /// be sent from consumer to producer; see SemiFuture/Future's `raise()` |
483 | /// and Promise's `setInterruptHandler()`. |
484 | /// |
485 | /// The consumer-side SemiFuture/Future objects should generally be accessed |
486 | /// via a single thread. That thread is referred to as the 'consumer thread.' |
487 | template <class T> |
488 | class SemiFuture : private futures::detail::FutureBase<T> { |
489 | private: |
490 | using Base = futures::detail::FutureBase<T>; |
491 | using DeferredExecutor = futures::detail::DeferredExecutor; |
492 | using TimePoint = std::chrono::system_clock::time_point; |
493 | |
494 | public: |
495 | ~SemiFuture(); |
496 | |
497 | /// Creates/returns an invalid SemiFuture, that is, one with no shared state. |
498 | /// |
499 | /// Postcondition: |
500 | /// |
501 | /// - `RESULT.valid() == false` |
502 | static SemiFuture<T> makeEmpty(); |
503 | |
504 | /// Type of the value that the producer, when successful, produces. |
505 | using typename Base::value_type; |
506 | |
507 | /// Construct a SemiFuture from a value (perfect forwarding) |
508 | /// |
509 | /// Postconditions: |
510 | /// |
511 | /// - `valid() == true` |
512 | /// - `isReady() == true` |
513 | /// - `hasValue() == true` |
514 | /// - `hasException() == false` |
515 | /// - `value()`, `get()`, `result()` will return the forwarded `T` |
516 | template < |
517 | class T2 = T, |
518 | typename = typename std::enable_if< |
519 | !isFuture<typename std::decay<T2>::type>::value && |
520 | !isSemiFuture<typename std::decay<T2>::type>::value>::type> |
521 | /* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {} |
522 | |
523 | /// Construct a (logical) SemiFuture-of-void. |
524 | /// |
525 | /// Postconditions: |
526 | /// |
527 | /// - `valid() == true` |
528 | /// - `isReady() == true` |
529 | /// - `hasValue() == true` |
530 | template <class T2 = T> |
531 | /* implicit */ SemiFuture( |
532 | typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr) |
533 | : Base(p) {} |
534 | |
535 | /// Construct a SemiFuture from a `T` constructed from `args` |
536 | /// |
537 | /// Postconditions: |
538 | /// |
539 | /// - `valid() == true` |
540 | /// - `isReady() == true` |
541 | /// - `hasValue() == true` |
542 | /// - `hasException() == false` |
543 | /// - `value()`, `get()`, `result()` will return the newly constructed `T` |
544 | template < |
545 | class... Args, |
546 | typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: |
547 | type = 0> |
548 | explicit SemiFuture(in_place_t, Args&&... args) |
549 | : Base(in_place, std::forward<Args>(args)...) {} |
550 | |
551 | SemiFuture(SemiFuture<T> const&) = delete; |
552 | // movable |
553 | SemiFuture(SemiFuture<T>&&) noexcept; |
554 | // safe move-constructabilty from Future |
555 | /* implicit */ SemiFuture(Future<T>&&) noexcept; |
556 | |
557 | using Base::cancel; |
558 | using Base::getPriority; |
559 | using Base::hasException; |
560 | using Base::hasValue; |
561 | using Base::isReady; |
562 | using Base::poll; |
563 | using Base::raise; |
564 | using Base::result; |
565 | using Base::setCallback_; |
566 | using Base::valid; |
567 | using Base::value; |
568 | |
569 | SemiFuture& operator=(SemiFuture const&) = delete; |
570 | SemiFuture& operator=(SemiFuture&&) noexcept; |
571 | SemiFuture& operator=(Future<T>&&) noexcept; |
572 | |
573 | /// Blocks until the promise is fulfilled, either by value (which is returned) |
574 | /// or exception (which is thrown). |
575 | /// |
576 | /// Preconditions: |
577 | /// |
578 | /// - `valid() == true` (else throws FutureInvalid) |
579 | /// - must not have a continuation, e.g., via `.thenValue()` or similar |
580 | /// |
581 | /// Postconditions: |
582 | /// |
583 | /// - `valid() == false` |
584 | T get() &&; |
585 | |
586 | [[deprecated("must be rvalue-qualified, e.g., std::move(future).get()" )]] T |
587 | get() & = delete; |
588 | |
589 | /// Blocks until the semifuture is fulfilled, or until `dur` elapses. Returns |
590 | /// the value (moved-out), or throws the exception (which might be a |
591 | /// FutureTimeout exception). |
592 | /// |
593 | /// Preconditions: |
594 | /// |
595 | /// - `valid() == true` (else throws FutureInvalid) |
596 | /// |
597 | /// Postconditions: |
598 | /// |
599 | /// - `valid() == false` |
600 | T get(Duration dur) &&; |
601 | |
602 | [[deprecated("must be rvalue-qualified, e.g., std::move(future).get(dur)" )]] T |
603 | get(Duration dur) & = delete; |
604 | |
605 | /// Blocks until the future is fulfilled. Returns the Try of the result |
606 | /// (moved-out). |
607 | /// |
608 | /// Preconditions: |
609 | /// |
610 | /// - `valid() == true` (else throws FutureInvalid) |
611 | /// |
612 | /// Postconditions: |
613 | /// |
614 | /// - `valid() == false` |
615 | Try<T> getTry() &&; |
616 | |
617 | /// Blocks until the future is fulfilled, or until `dur` elapses. |
618 | /// Returns the Try of the result (moved-out), or throws FutureTimeout |
619 | /// exception. |
620 | /// |
621 | /// Preconditions: |
622 | /// |
623 | /// - `valid() == true` (else throws FutureInvalid) |
624 | /// |
625 | /// Postconditions: |
626 | /// |
627 | /// - `valid() == false` |
628 | Try<T> getTry(Duration dur) &&; |
629 | |
630 | /// Blocks the caller's thread until this Future `isReady()`, i.e., until the |
631 | /// asynchronous producer has stored a result or exception. |
632 | /// |
633 | /// Preconditions: |
634 | /// |
635 | /// - `valid() == true` (else throws FutureInvalid) |
636 | /// |
637 | /// Postconditions: |
638 | /// |
639 | /// - `valid() == true` |
640 | /// - `isReady() == true` |
641 | /// - `&RESULT == this` |
642 | SemiFuture<T>& wait() &; |
643 | |
644 | /// Blocks the caller's thread until this Future `isReady()`, i.e., until the |
645 | /// asynchronous producer has stored a result or exception. |
646 | /// |
647 | /// Preconditions: |
648 | /// |
649 | /// - `valid() == true` (else throws FutureInvalid) |
650 | /// |
651 | /// Postconditions: |
652 | /// |
653 | /// - `valid() == true` (but the calling code can trivially move-out `*this` |
654 | /// by assigning or constructing the result into a distinct object). |
655 | /// - `&RESULT == this` |
656 | /// - `isReady() == true` |
657 | SemiFuture<T>&& wait() &&; |
658 | |
659 | /// Blocks until the future is fulfilled, or `dur` elapses. |
660 | /// Returns true if the future was fulfilled. |
661 | /// |
662 | /// Preconditions: |
663 | /// |
664 | /// - `valid() == true` (else throws FutureInvalid) |
665 | /// |
666 | /// Postconditions: |
667 | /// |
668 | /// - `valid() == false` |
669 | bool wait(Duration dur) &&; |
670 | |
671 | /// Returns a Future which will call back on the other side of executor. |
672 | Future<T> via(Executor* executor, int8_t priority = Executor::MID_PRI) &&; |
673 | |
674 | Future<T> via( |
675 | Executor::KeepAlive<> executor, |
676 | int8_t priority = Executor::MID_PRI) &&; |
677 | |
678 | /// Defer work to run on the consumer of the future. |
679 | /// Function must take a Try as a parameter. |
680 | /// This work will be run either on an executor that the caller sets on the |
681 | /// SemiFuture, or inline with the call to .get(). |
682 | /// |
683 | /// NB: This is a custom method because boost-blocking executors is a |
684 | /// special-case for work deferral in folly. With more general boost-blocking |
685 | /// support all executors would boost block and we would simply use some form |
686 | /// of driveable executor here. |
687 | /// |
688 | /// Preconditions: |
689 | /// |
690 | /// - `valid() == true` (else throws FutureInvalid) |
691 | /// |
692 | /// Postconditions: |
693 | /// |
694 | /// - `valid() == false` |
695 | /// - `RESULT.valid() == true` |
696 | template <typename F> |
697 | SemiFuture<typename futures::detail::tryCallableResult<T, F>::value_type> |
698 | defer(F&& func) &&; |
699 | |
700 | template <typename F> |
701 | SemiFuture< |
702 | typename futures::detail::tryExecutorCallableResult<T, F>::value_type> |
703 | defer(F&& func) &&; |
704 | |
705 | template <typename R, typename... 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 | /// Preconditions: |
713 | /// |
714 | /// - `valid() == true` (else throws FutureInvalid) |
715 | /// |
716 | /// Postconditions: |
717 | /// |
718 | /// - `valid() == false` |
719 | /// - `RESULT.valid() == true` |
720 | template <typename F> |
721 | SemiFuture<typename futures::detail::valueCallableResult<T, F>::value_type> |
722 | deferValue(F&& func) &&; |
723 | |
724 | template <typename R, typename... Args> |
725 | auto deferValue(R (&func)(Args...)) && { |
726 | return std::move(*this).deferValue(&func); |
727 | } |
728 | |
729 | /// Set an error continuation for this SemiFuture where the continuation can |
730 | /// be called with a known exception type and returns a `T`, `Future<T>`, or |
731 | /// `SemiFuture<T>`. |
732 | /// |
733 | /// Example: |
734 | /// |
735 | /// ``` |
736 | /// makeSemiFuture() |
737 | /// .defer([] { |
738 | /// throw std::runtime_error("oh no!"); |
739 | /// return 42; |
740 | /// }) |
741 | /// .deferError<std::runtime_error>([] (auto const& e) { |
742 | /// LOG(INFO) << "std::runtime_error: " << e.what(); |
743 | /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1) |
744 | /// }); |
745 | /// ``` |
746 | /// |
747 | /// Preconditions: |
748 | /// |
749 | /// - `valid() == true` (else throws FutureInvalid) |
750 | /// |
751 | /// Postconditions: |
752 | /// |
753 | /// - `valid() == false` |
754 | /// - `RESULT.valid() == true` |
755 | template <class ExceptionType, class F> |
756 | SemiFuture<T> deferError(F&& func) &&; |
757 | |
758 | template <class ExceptionType, class R, class... Args> |
759 | SemiFuture<T> deferError(R (&func)(Args...)) && { |
760 | return std::move(*this).template deferError<ExceptionType>(&func); |
761 | } |
762 | |
763 | /// Set an error continuation for this SemiFuture where the continuation can |
764 | /// be called with `exception_wrapper&&` and returns a `T`, `Future<T>`, or |
765 | /// `SemiFuture<T>`. |
766 | /// |
767 | /// Example: |
768 | /// |
769 | /// makeSemiFuture() |
770 | /// .defer([] { |
771 | /// throw std::runtime_error("oh no!"); |
772 | /// return 42; |
773 | /// }) |
774 | /// .deferError([] (exception_wrapper&& e) { |
775 | /// LOG(INFO) << e.what(); |
776 | /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1) |
777 | /// }); |
778 | /// |
779 | /// Preconditions: |
780 | /// |
781 | /// - `valid() == true` (else throws FutureInvalid) |
782 | /// |
783 | /// Postconditions: |
784 | /// |
785 | /// - `valid() == false` |
786 | /// - `RESULT.valid() == true` |
787 | template <class F> |
788 | SemiFuture<T> deferError(F&& func) &&; |
789 | |
790 | template <class R, class... Args> |
791 | SemiFuture<T> deferError(R (&func)(Args...)) && { |
792 | return std::move(*this).deferError(&func); |
793 | } |
794 | |
795 | SemiFuture<T> within(Duration dur, Timekeeper* tk = nullptr) && { |
796 | return std::move(*this).within(dur, FutureTimeout(), tk); |
797 | } |
798 | |
799 | template <class E> |
800 | SemiFuture<T> within(Duration dur, E e, Timekeeper* tk = nullptr) && { |
801 | return this->isReady() ? std::move(*this) |
802 | : std::move(*this).withinImplementation(dur, e, tk); |
803 | } |
804 | |
805 | /// Delay the completion of this SemiFuture for at least this duration from |
806 | /// now. The optional Timekeeper is as with futures::sleep(). |
807 | /// |
808 | /// Preconditions: |
809 | /// |
810 | /// - `valid() == true` (else throws FutureInvalid) |
811 | /// |
812 | /// Postconditions: |
813 | /// |
814 | /// - `valid() == false` |
815 | /// - `RESULT.valid() == true` |
816 | SemiFuture<T> delayed(Duration dur, Timekeeper* tk = nullptr) &&; |
817 | |
818 | /// Returns a future that completes inline, as if the future had no executor. |
819 | /// Intended for porting legacy code without behavioral change, and for rare |
820 | /// cases where this is really the intended behavior. |
821 | /// Future is unsafe in the sense that the executor it completes on is |
822 | /// non-deterministic in the standard case. |
823 | /// For new code, or to update code that temporarily uses this, please |
824 | /// use via and pass a meaningful executor. |
825 | /// |
826 | /// Preconditions: |
827 | /// |
828 | /// - `valid() == true` (else throws FutureInvalid) |
829 | /// |
830 | /// Postconditions: |
831 | /// |
832 | /// - `valid() == false` |
833 | /// - `RESULT.valid() == true` |
834 | Future<T> toUnsafeFuture() &&; |
835 | |
836 | #if FOLLY_HAS_COROUTINES |
837 | |
838 | // Customise the co_viaIfAsync() operator so that SemiFuture<T> can be |
839 | // directly awaited within a folly::coro::Task coroutine. |
840 | friend Future<T> co_viaIfAsync( |
841 | folly::Executor* executor, |
842 | SemiFuture<T>&& future) noexcept { |
843 | return std::move(future).via(executor); |
844 | } |
845 | |
846 | #endif |
847 | |
848 | private: |
849 | friend class Promise<T>; |
850 | template <class> |
851 | friend class futures::detail::FutureBase; |
852 | template <class> |
853 | friend class SemiFuture; |
854 | template <class> |
855 | friend class Future; |
856 | friend folly::Executor::KeepAlive<DeferredExecutor> |
857 | futures::detail::stealDeferredExecutor<T>(SemiFuture&); |
858 | friend DeferredExecutor* futures::detail::getDeferredExecutor<T>(SemiFuture&); |
859 | |
860 | using Base::setExecutor; |
861 | using Base::throwIfInvalid; |
862 | using typename Base::Core; |
863 | |
864 | template <class T2> |
865 | friend SemiFuture<T2> makeSemiFuture(Try<T2>); |
866 | |
867 | explicit SemiFuture(Core* obj) : Base(obj) {} |
868 | |
869 | explicit SemiFuture(futures::detail::EmptyConstruct) noexcept |
870 | : Base(futures::detail::EmptyConstruct{}) {} |
871 | |
872 | // Throws FutureInvalid if !this->core_ |
873 | DeferredExecutor* getDeferredExecutor() const; |
874 | |
875 | // Throws FutureInvalid if !this->core_ |
876 | folly::Executor::KeepAlive<DeferredExecutor> stealDeferredExecutor() const; |
877 | |
878 | /// Blocks until the future is fulfilled, or `dur` elapses. |
879 | /// |
880 | /// Preconditions: |
881 | /// |
882 | /// - `valid() == true` (else throws FutureInvalid) |
883 | /// |
884 | /// Postconditions: |
885 | /// |
886 | /// - `valid() == true` |
887 | /// - `&RESULT == this` |
888 | /// - `isReady()` will be indeterminate - may or may not be true |
889 | SemiFuture<T>& wait(Duration dur) &; |
890 | |
891 | static void releaseDeferredExecutor(Core* core); |
892 | }; |
893 | |
894 | template <class T> |
895 | std::pair<Promise<T>, SemiFuture<T>> makePromiseContract() { |
896 | auto p = Promise<T>(); |
897 | auto f = p.getSemiFuture(); |
898 | return std::make_pair(std::move(p), std::move(f)); |
899 | } |
900 | |
901 | /// The interface (along with SemiFuture) for the consumer-side of a |
902 | /// producer/consumer pair. |
903 | /// |
904 | /// Future vs. SemiFuture: |
905 | /// |
906 | /// - The consumer-side should generally start with a SemiFuture, not a Future. |
907 | /// - Example, when a library creates and returns a future, it should usually |
908 | /// return a `SemiFuture`, not a Future. |
909 | /// - Reason: so the thread policy for continuations (`.thenValue`, etc.) can be |
910 | /// specified by the library's caller (using `.via()`). |
911 | /// - A SemiFuture is converted to a Future using `.via()`. |
912 | /// - Use `makePromiseContract()` when creating both a Promise and an associated |
913 | /// SemiFuture/Future. |
914 | /// |
915 | /// When practical, prefer SemiFuture/Future's nonblocking style/pattern: |
916 | /// |
917 | /// - the nonblocking style uses continuations, e.g., `.thenValue`, etc.; the |
918 | /// continuations are deferred until the result is available. |
919 | /// - the blocking style blocks until complete, e.g., `.wait()`, `.get()`, etc. |
920 | /// - the two styles cannot be mixed within the same future; use one or the |
921 | /// other. |
922 | /// |
923 | /// SemiFuture/Future also provide a back-channel so an interrupt can |
924 | /// be sent from consumer to producer; see SemiFuture/Future's `raise()` |
925 | /// and Promise's `setInterruptHandler()`. |
926 | /// |
927 | /// The consumer-side SemiFuture/Future objects should generally be accessed |
928 | /// via a single thread. That thread is referred to as the 'consumer thread.' |
929 | template <class T> |
930 | class Future : private futures::detail::FutureBase<T> { |
931 | private: |
932 | using Base = futures::detail::FutureBase<T>; |
933 | |
934 | public: |
935 | /// Type of the value that the producer, when successful, produces. |
936 | using typename Base::value_type; |
937 | |
938 | /// Construct a Future from a value (perfect forwarding) |
939 | /// |
940 | /// Postconditions: |
941 | /// |
942 | /// - `valid() == true` |
943 | /// - `isReady() == true` |
944 | /// - `hasValue() == true` |
945 | /// - `value()`, `get()`, `result()` will return the forwarded `T` |
946 | template < |
947 | class T2 = T, |
948 | typename = typename std::enable_if< |
949 | !isFuture<typename std::decay<T2>::type>::value && |
950 | !isSemiFuture<typename std::decay<T2>::type>::value>::type> |
951 | /* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {} |
952 | |
953 | /// Construct a (logical) Future-of-void. |
954 | /// |
955 | /// Postconditions: |
956 | /// |
957 | /// - `valid() == true` |
958 | /// - `isReady() == true` |
959 | /// - `hasValue() == true` |
960 | template <class T2 = T> |
961 | /* implicit */ Future( |
962 | typename std::enable_if<std::is_same<Unit, T2>::value>::type* p = nullptr) |
963 | : Base(p) {} |
964 | |
965 | /// Construct a Future from a `T` constructed from `args` |
966 | /// |
967 | /// Postconditions: |
968 | /// |
969 | /// - `valid() == true` |
970 | /// - `isReady() == true` |
971 | /// - `hasValue() == true` |
972 | /// - `hasException() == false` |
973 | /// - `value()`, `get()`, `result()` will return the newly constructed `T` |
974 | template < |
975 | class... Args, |
976 | typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: |
977 | type = 0> |
978 | explicit Future(in_place_t, Args&&... args) |
979 | : Base(in_place, std::forward<Args>(args)...) {} |
980 | |
981 | Future(Future<T> const&) = delete; |
982 | // movable |
983 | Future(Future<T>&&) noexcept; |
984 | |
985 | // converting move |
986 | template < |
987 | class T2, |
988 | typename std::enable_if< |
989 | !std::is_same<T, typename std::decay<T2>::type>::value && |
990 | std::is_constructible<T, T2&&>::value && |
991 | std::is_convertible<T2&&, T>::value, |
992 | int>::type = 0> |
993 | /* implicit */ Future(Future<T2>&&); |
994 | template < |
995 | class T2, |
996 | typename std::enable_if< |
997 | !std::is_same<T, typename std::decay<T2>::type>::value && |
998 | std::is_constructible<T, T2&&>::value && |
999 | !std::is_convertible<T2&&, T>::value, |
1000 | int>::type = 0> |
1001 | explicit Future(Future<T2>&&); |
1002 | template < |
1003 | class T2, |
1004 | typename std::enable_if< |
1005 | !std::is_same<T, typename std::decay<T2>::type>::value && |
1006 | std::is_constructible<T, T2&&>::value, |
1007 | int>::type = 0> |
1008 | Future& operator=(Future<T2>&&); |
1009 | |
1010 | using Base::cancel; |
1011 | using Base::getPriority; |
1012 | using Base::hasException; |
1013 | using Base::hasValue; |
1014 | using Base::isReady; |
1015 | using Base::poll; |
1016 | using Base::raise; |
1017 | using Base::result; |
1018 | using Base::setCallback_; |
1019 | using Base::valid; |
1020 | using Base::value; |
1021 | |
1022 | /// Creates/returns an invalid Future, that is, one with no shared state. |
1023 | /// |
1024 | /// Postcondition: |
1025 | /// |
1026 | /// - `RESULT.valid() == false` |
1027 | static Future<T> makeEmpty(); |
1028 | |
1029 | // not copyable |
1030 | Future& operator=(Future const&) = delete; |
1031 | |
1032 | // movable |
1033 | Future& operator=(Future&&) noexcept; |
1034 | |
1035 | /// Call e->drive() repeatedly until the future is fulfilled. |
1036 | /// |
1037 | /// Examples of DrivableExecutor include EventBase and ManualExecutor. |
1038 | /// |
1039 | /// Returns the fulfilled value (moved-out) or throws the fulfilled exception. |
1040 | T getVia(DrivableExecutor* e); |
1041 | |
1042 | /// Call e->drive() repeatedly until the future is fulfilled, or `dur` |
1043 | /// elapses. |
1044 | /// |
1045 | /// Returns the fulfilled value (moved-out), throws the fulfilled exception, |
1046 | /// or on timeout throws FutureTimeout. |
1047 | T getVia(TimedDrivableExecutor* e, Duration dur); |
1048 | |
1049 | /// Call e->drive() repeatedly until the future is fulfilled. Examples |
1050 | /// of DrivableExecutor include EventBase and ManualExecutor. Returns a |
1051 | /// reference to the Try of the value. |
1052 | Try<T>& getTryVia(DrivableExecutor* e); |
1053 | |
1054 | /// getTryVia but will wait only until `dur` elapses. Returns the |
1055 | /// Try of the value (moved-out) or may throw a FutureTimeout exception. |
1056 | Try<T>& getTryVia(TimedDrivableExecutor* e, Duration dur); |
1057 | |
1058 | /// Unwraps the case of a Future<Future<T>> instance, and returns a simple |
1059 | /// Future<T> instance. |
1060 | /// |
1061 | /// Preconditions: |
1062 | /// |
1063 | /// - `valid() == true` (else throws FutureInvalid) |
1064 | /// |
1065 | /// Postconditions: |
1066 | /// |
1067 | /// - Calling code should act as if `valid() == false`, |
1068 | /// i.e., as if `*this` was moved into RESULT. |
1069 | /// - `RESULT.valid() == true` |
1070 | template <class F = T> |
1071 | typename std:: |
1072 | enable_if<isFuture<F>::value, Future<typename isFuture<T>::Inner>>::type |
1073 | unwrap() &&; |
1074 | |
1075 | /// Returns a Future which will call back on the other side of executor. |
1076 | /// |
1077 | /// Preconditions: |
1078 | /// |
1079 | /// - `valid() == true` (else throws FutureInvalid) |
1080 | /// |
1081 | /// Postconditions: |
1082 | /// |
1083 | /// - `valid() == false` |
1084 | /// - `RESULT.valid() == true` |
1085 | Future<T> via(Executor* executor, int8_t priority = Executor::MID_PRI) &&; |
1086 | |
1087 | Future<T> via( |
1088 | Executor::KeepAlive<> executor, |
1089 | int8_t priority = Executor::MID_PRI) &&; |
1090 | |
1091 | /// Returns a Future which will call back on the other side of executor. |
1092 | /// |
1093 | /// When practical, use the rvalue-qualified overload instead - it's faster. |
1094 | /// |
1095 | /// Preconditions: |
1096 | /// |
1097 | /// - `valid() == true` (else throws FutureInvalid) |
1098 | /// |
1099 | /// Postconditions: |
1100 | /// |
1101 | /// - `valid() == true` |
1102 | /// - `RESULT.valid() == true` |
1103 | /// - when `this` gets fulfilled, it automatically fulfills RESULT |
1104 | Future<T> via(Executor* executor, int8_t priority = Executor::MID_PRI) &; |
1105 | |
1106 | Future<T> via( |
1107 | Executor::KeepAlive<> executor, |
1108 | int8_t priority = Executor::MID_PRI) &; |
1109 | |
1110 | /// When this Future has completed, execute func which is a function that |
1111 | /// can be called with either `T&&` or `Try<T>&&`. |
1112 | /// |
1113 | /// Func shall return either another Future or a value. |
1114 | /// |
1115 | /// A Future for the return type of func is returned. |
1116 | /// |
1117 | /// Future<string> f2 = f1.thenTry([](Try<T>&&) { return string("foo"); }); |
1118 | /// |
1119 | /// Preconditions: |
1120 | /// |
1121 | /// - `valid() == true` (else throws FutureInvalid) |
1122 | /// |
1123 | /// Postconditions: |
1124 | /// |
1125 | /// - Calling code should act as if `valid() == false`, |
1126 | /// i.e., as if `*this` was moved into RESULT. |
1127 | /// - `RESULT.valid() == true` |
1128 | /// NOTE: All three of these variations are deprecated and deprecation |
1129 | /// attributes will be added in the near future. Please prefer thenValue, |
1130 | /// thenTry or thenError rather than then and onError as they avoid ambiguity |
1131 | /// when using polymorphic lambdas. |
1132 | template <typename F, typename R = futures::detail::callableResult<T, F>> |
1133 | [[deprecated("ERROR: use thenValue instead" )]] typename std::enable_if< |
1134 | !is_invocable<F>::value && is_invocable<F, T&&>::value, |
1135 | typename R::Return>::type |
1136 | then(F&& func) && = delete; |
1137 | |
1138 | template <typename F, typename R = futures::detail::callableResult<T, F>> |
1139 | [[deprecated("ERROR: use thenTry instead" )]] typename std::enable_if< |
1140 | !is_invocable<F, T&&>::value && !is_invocable<F>::value, |
1141 | typename R::Return>::type |
1142 | then(F&& func) && { |
1143 | return std::move(*this).thenTry(std::forward<F>(func)); |
1144 | } |
1145 | |
1146 | template <typename F, typename R = futures::detail::callableResult<T, F>> |
1147 | [[deprecated( |
1148 | "ERROR: use thenValue with auto&& or folly::Unit parameter instead" )]] |
1149 | typename std::enable_if<is_invocable<F>::value, typename R::Return>::type |
1150 | then(F&& func) && = delete; |
1151 | |
1152 | // clang-format off |
1153 | template <typename F, typename R = futures::detail::callableResult<T, F>> |
1154 | [[deprecated( |
1155 | "must be rvalue-qualified, e.g., std::move(future).thenValue(...)" )]] |
1156 | typename R::Return then(F&& func) & = delete; |
1157 | // clang-format on |
1158 | |
1159 | /// Variant where func is an member function |
1160 | /// |
1161 | /// struct Worker { R doWork(Try<T>); } |
1162 | /// |
1163 | /// Worker *w; |
1164 | /// Future<R> f2 = f1.thenTry(&Worker::doWork, w); |
1165 | /// |
1166 | /// This is just sugar for |
1167 | /// |
1168 | /// f1.thenTry(std::bind(&Worker::doWork, w)); |
1169 | /// |
1170 | /// Preconditions: |
1171 | /// |
1172 | /// - `valid() == true` (else throws FutureInvalid) |
1173 | /// |
1174 | /// Postconditions: |
1175 | /// |
1176 | /// - Calling code should act as if `valid() == false`, |
1177 | /// i.e., as if `*this` was moved into RESULT. |
1178 | /// - `RESULT.valid() == true` |
1179 | template <typename R, typename Caller, typename... Args> |
1180 | Future<typename isFuture<R>::Inner> then( |
1181 | R (Caller::*func)(Args...), |
1182 | Caller* instance) &&; |
1183 | |
1184 | // clang-format off |
1185 | template <typename R, typename Caller, typename... Args> |
1186 | [[deprecated( |
1187 | "must be rvalue-qualified, e.g., std::move(future).then(...)" )]] |
1188 | Future<typename isFuture<R>::Inner> |
1189 | then(R (Caller::*func)(Args...), Caller* instance) & = delete; |
1190 | // clang-format on |
1191 | |
1192 | /// Execute the callback via the given Executor. The executor doesn't stick. |
1193 | /// |
1194 | /// Contrast |
1195 | /// |
1196 | /// f.via(x).then(b).then(c) |
1197 | /// |
1198 | /// with |
1199 | /// |
1200 | /// f.then(x, b).then(c) |
1201 | /// |
1202 | /// In the former both b and c execute via x. In the latter, only b executes |
1203 | /// via x, and c executes via the same executor (if any) that f had. |
1204 | /// |
1205 | /// Preconditions: |
1206 | /// |
1207 | /// - `valid() == true` (else throws FutureInvalid) |
1208 | /// |
1209 | /// Postconditions: |
1210 | /// |
1211 | /// - Calling code should act as if `valid() == false`, |
1212 | /// i.e., as if `*this` was moved into RESULT. |
1213 | /// - `RESULT.valid() == true` |
1214 | template <class Arg> |
1215 | auto then(Executor* x, Arg&& arg) && { |
1216 | auto oldX = this->getExecutor(); |
1217 | this->setExecutor(x); |
1218 | |
1219 | // TODO(T29171940): thenImplementation here is ambiguous |
1220 | // as then used to be but that is better than keeping then in the public |
1221 | // API. |
1222 | using R = futures::detail::callableResult<T, Arg&&>; |
1223 | return std::move(*this) |
1224 | .thenImplementation(std::forward<Arg>(arg), R{}) |
1225 | .via(oldX); |
1226 | } |
1227 | |
1228 | template <class R, class Caller, class... Args> |
1229 | auto then(Executor* x, R (Caller::*func)(Args...), Caller* instance) && { |
1230 | auto oldX = this->getExecutor(); |
1231 | this->setExecutor(x); |
1232 | |
1233 | return std::move(*this).then(func, instance).via(oldX); |
1234 | } |
1235 | |
1236 | template <class Arg, class... Args> |
1237 | [[deprecated( |
1238 | "must be rvalue-qualified, e.g., std::move(future).then(...)" )]] auto |
1239 | then(Executor* x, Arg&& arg, Args&&... args) & = delete; |
1240 | |
1241 | /// When this Future has completed, execute func which is a function that |
1242 | /// can be called with `Try<T>&&` (often a lambda with parameter type |
1243 | /// `auto&&` or `auto`). |
1244 | /// |
1245 | /// Func shall return either another Future or a value. |
1246 | /// |
1247 | /// A Future for the return type of func is returned. |
1248 | /// |
1249 | /// Future<string> f2 = std::move(f1).thenTry([](auto&& t) { |
1250 | /// ... |
1251 | /// return string("foo"); |
1252 | /// }); |
1253 | /// |
1254 | /// Preconditions: |
1255 | /// |
1256 | /// - `valid() == true` (else throws FutureInvalid) |
1257 | /// |
1258 | /// Postconditions: |
1259 | /// |
1260 | /// - `valid() == false` |
1261 | /// - `RESULT.valid() == true` |
1262 | template <typename F> |
1263 | Future<typename futures::detail::tryCallableResult<T, F>::value_type> thenTry( |
1264 | F&& func) &&; |
1265 | |
1266 | template <typename R, typename... Args> |
1267 | auto thenTry(R (&func)(Args...)) && { |
1268 | return std::move(*this).thenTry(&func); |
1269 | } |
1270 | |
1271 | /// When this Future has completed, execute func which is a function that |
1272 | /// can be called with `T&&` (often a lambda with parameter type |
1273 | /// `auto&&` or `auto`). |
1274 | /// |
1275 | /// Func shall return either another Future or a value. |
1276 | /// |
1277 | /// A Future for the return type of func is returned. |
1278 | /// |
1279 | /// Future<string> f2 = f1.thenValue([](auto&& v) { |
1280 | /// ... |
1281 | /// return string("foo"); |
1282 | /// }); |
1283 | /// |
1284 | /// Preconditions: |
1285 | /// |
1286 | /// - `valid() == true` (else throws FutureInvalid) |
1287 | /// |
1288 | /// Postconditions: |
1289 | /// |
1290 | /// - `valid() == false` |
1291 | /// - `RESULT.valid() == true` |
1292 | template <typename F> |
1293 | Future<typename futures::detail::valueCallableResult<T, F>::value_type> |
1294 | thenValue(F&& func) &&; |
1295 | |
1296 | template <typename R, typename... Args> |
1297 | auto thenValue(R (&func)(Args...)) && { |
1298 | return std::move(*this).thenValue(&func); |
1299 | } |
1300 | |
1301 | /// Set an error continuation for this Future where the continuation can |
1302 | /// be called with a known exception type and returns a `T`, `Future<T>`, or |
1303 | /// `SemiFuture<T>`. |
1304 | /// |
1305 | /// Example: |
1306 | /// |
1307 | /// makeFuture() |
1308 | /// .thenTry([] { |
1309 | /// throw std::runtime_error("oh no!"); |
1310 | /// return 42; |
1311 | /// }) |
1312 | /// .thenError<std::runtime_error>([] (auto const& e) { |
1313 | /// LOG(INFO) << "std::runtime_error: " << e.what(); |
1314 | /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1) |
1315 | /// }); |
1316 | /// |
1317 | /// Preconditions: |
1318 | /// |
1319 | /// - `valid() == true` (else throws FutureInvalid) |
1320 | /// |
1321 | /// Postconditions: |
1322 | /// |
1323 | /// - `valid() == false` |
1324 | /// - `RESULT.valid() == true` |
1325 | template <class ExceptionType, class F> |
1326 | Future<T> thenError(F&& func) &&; |
1327 | |
1328 | template <class ExceptionType, class R, class... Args> |
1329 | Future<T> thenError(R (&func)(Args...)) && { |
1330 | return std::move(*this).template thenError<ExceptionType>(&func); |
1331 | } |
1332 | |
1333 | /// Set an error continuation for this Future where the continuation can |
1334 | /// be called with `exception_wrapper&&` and returns a `T`, `Future<T>`, or |
1335 | /// `SemiFuture<T>`. |
1336 | /// |
1337 | /// Example: |
1338 | /// |
1339 | /// makeFuture() |
1340 | /// .thenTry([] { |
1341 | /// throw std::runtime_error("oh no!"); |
1342 | /// return 42; |
1343 | /// }) |
1344 | /// .thenError([] (exception_wrapper&& e) { |
1345 | /// LOG(INFO) << e.what(); |
1346 | /// return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1) |
1347 | /// }); |
1348 | /// |
1349 | /// Preconditions: |
1350 | /// |
1351 | /// - `valid() == true` (else throws FutureInvalid) |
1352 | /// |
1353 | /// Postconditions: |
1354 | /// |
1355 | /// - `valid() == false` |
1356 | /// - `RESULT.valid() == true` |
1357 | template <class F> |
1358 | Future<T> thenError(F&& func) &&; |
1359 | |
1360 | template <class R, class... Args> |
1361 | Future<T> thenError(R (&func)(Args...)) && { |
1362 | return std::move(*this).thenError(&func); |
1363 | } |
1364 | |
1365 | /// Convenience method for ignoring the value and creating a Future<Unit>. |
1366 | /// Exceptions still propagate. |
1367 | /// This function is identical to .unit(). |
1368 | /// |
1369 | /// Preconditions: |
1370 | /// |
1371 | /// - `valid() == true` (else throws FutureInvalid) |
1372 | /// |
1373 | /// Postconditions: |
1374 | /// |
1375 | /// - Calling code should act as if `valid() == false`, |
1376 | /// i.e., as if `*this` was moved into RESULT. |
1377 | /// - `RESULT.valid() == true` |
1378 | Future<Unit> then() &&; |
1379 | |
1380 | // clang-format off |
1381 | [[deprecated( |
1382 | "must be rvalue-qualified, e.g., std::move(future).thenValue()" )]] |
1383 | Future<Unit> then() & = delete; |
1384 | // clang-format on |
1385 | |
1386 | /// Convenience method for ignoring the value and creating a Future<Unit>. |
1387 | /// Exceptions still propagate. |
1388 | /// This function is identical to parameterless .then(). |
1389 | /// |
1390 | /// Preconditions: |
1391 | /// |
1392 | /// - `valid() == true` (else throws FutureInvalid) |
1393 | /// |
1394 | /// Postconditions: |
1395 | /// |
1396 | /// - Calling code should act as if `valid() == false`, |
1397 | /// i.e., as if `*this` was moved into RESULT. |
1398 | /// - `RESULT.valid() == true` |
1399 | Future<Unit> unit() && { |
1400 | return std::move(*this).then(); |
1401 | } |
1402 | |
1403 | /// Set an error continuation for this Future. The continuation should take an |
1404 | /// argument of the type that you want to catch, and should return a value of |
1405 | /// the same type as this Future, or a Future of that type (see overload |
1406 | /// below). |
1407 | /// |
1408 | /// Example: |
1409 | /// |
1410 | /// makeFuture() |
1411 | /// .thenValue([] { |
1412 | /// throw std::runtime_error("oh no!"); |
1413 | /// return 42; |
1414 | /// }) |
1415 | /// .thenError<std::runtime_error>([] (std::runtime_error& e) { |
1416 | /// LOG(INFO) << "std::runtime_error: " << e.what(); |
1417 | /// return -1; // or makeFuture<int>(-1) |
1418 | /// }); |
1419 | /// |
1420 | /// Preconditions: |
1421 | /// |
1422 | /// - `valid() == true` (else throws FutureInvalid) |
1423 | /// |
1424 | /// Postconditions: |
1425 | /// |
1426 | /// - Calling code should act as if `valid() == false`, |
1427 | /// i.e., as if `*this` was moved into RESULT. |
1428 | /// - `RESULT.valid() == true` |
1429 | template <class F> |
1430 | [[deprecated( |
1431 | "onError loses the attached executor and is weakly typed. Please move to thenError instead." )]] |
1432 | typename std::enable_if< |
1433 | !is_invocable<F, exception_wrapper>::value && |
1434 | !futures::detail::Extract<F>::ReturnsFuture::value, |
1435 | Future<T>>::type |
1436 | onError(F&& func) &&; |
1437 | |
1438 | /// Overload of onError where the error continuation returns a Future<T> |
1439 | /// |
1440 | /// Preconditions: |
1441 | /// |
1442 | /// - `valid() == true` (else throws FutureInvalid) |
1443 | /// |
1444 | /// Postconditions: |
1445 | /// |
1446 | /// - Calling code should act as if `valid() == false`, |
1447 | /// i.e., as if `*this` was moved into RESULT. |
1448 | /// - `RESULT.valid() == true` |
1449 | template <class F> |
1450 | [[deprecated( |
1451 | "onError loses the attached executor and is weakly typed. Please move to thenError instead." )]] |
1452 | typename std::enable_if< |
1453 | !is_invocable<F, exception_wrapper>::value && |
1454 | futures::detail::Extract<F>::ReturnsFuture::value, |
1455 | Future<T>>::type |
1456 | onError(F&& func) &&; |
1457 | |
1458 | /// Overload of onError that takes exception_wrapper and returns Future<T> |
1459 | /// |
1460 | /// Preconditions: |
1461 | /// |
1462 | /// - `valid() == true` (else throws FutureInvalid) |
1463 | /// |
1464 | /// Postconditions: |
1465 | /// |
1466 | /// - Calling code should act as if `valid() == false`, |
1467 | /// i.e., as if `*this` was moved into RESULT. |
1468 | /// - `RESULT.valid() == true` |
1469 | template <class F> |
1470 | [[deprecated( |
1471 | "onError loses the attached executor and is weakly typed. Please move to thenError instead." )]] |
1472 | typename std::enable_if< |
1473 | is_invocable<F, exception_wrapper>::value && |
1474 | futures::detail::Extract<F>::ReturnsFuture::value, |
1475 | Future<T>>::type |
1476 | onError(F&& func) &&; |
1477 | |
1478 | /// Overload of onError that takes exception_wrapper and returns T |
1479 | /// |
1480 | /// Preconditions: |
1481 | /// |
1482 | /// - `valid() == true` (else throws FutureInvalid) |
1483 | /// |
1484 | /// Postconditions: |
1485 | /// |
1486 | /// - Calling code should act as if `valid() == false`, |
1487 | /// i.e., as if `*this` was moved into RESULT. |
1488 | /// - `RESULT.valid() == true` |
1489 | template <class F> |
1490 | [[deprecated( |
1491 | "onError loses the attached executor and is weakly typed. Please move to thenError instead." )]] |
1492 | typename std::enable_if< |
1493 | is_invocable<F, exception_wrapper>::value && |
1494 | !futures::detail::Extract<F>::ReturnsFuture::value, |
1495 | Future<T>>::type |
1496 | onError(F&& func) &&; |
1497 | |
1498 | // clang-format off |
1499 | template <class F> |
1500 | [[deprecated("ERROR: use rvalue-qualified fn, eg, std::move(future).onError(...)" )]] |
1501 | Future<T> onError(F&& func) & = delete; |
1502 | |
1503 | /// func is like std::function<void()> and is executed unconditionally, and |
1504 | /// the value/exception is passed through to the resulting Future. |
1505 | /// func shouldn't throw, but if it does it will be captured and propagated, |
1506 | /// and discard any value/exception that this Future has obtained. |
1507 | /// |
1508 | /// Preconditions: |
1509 | /// |
1510 | /// - `valid() == true` (else throws FutureInvalid) |
1511 | /// |
1512 | /// Postconditions: |
1513 | /// |
1514 | /// - Calling code should act as if `valid() == false`, |
1515 | /// i.e., as if `*this` was moved into RESULT. |
1516 | /// - `RESULT.valid() == true` |
1517 | template <class F> |
1518 | Future<T> ensure(F&& func) &&; |
1519 | // clang-format on |
1520 | |
1521 | /// Like onError, but for timeouts. example: |
1522 | /// |
1523 | /// Future<int> f = makeFuture<int>(42) |
1524 | /// .delayed(long_time) |
1525 | /// .onTimeout(short_time, |
1526 | /// [] { return -1; }); |
1527 | /// |
1528 | /// or perhaps |
1529 | /// |
1530 | /// Future<int> f = makeFuture<int>(42) |
1531 | /// .delayed(long_time) |
1532 | /// .onTimeout(short_time, |
1533 | /// [] { return makeFuture<int>(some_exception); }); |
1534 | /// |
1535 | /// Preconditions: |
1536 | /// |
1537 | /// - `valid() == true` (else throws FutureInvalid) |
1538 | /// |
1539 | /// Postconditions: |
1540 | /// |
1541 | /// - Calling code should act as if `valid() == false`, |
1542 | /// i.e., as if `*this` was moved into RESULT. |
1543 | /// - `RESULT.valid() == true` |
1544 | template <class F> |
1545 | Future<T> onTimeout(Duration, F&& func, Timekeeper* = nullptr) &&; |
1546 | |
1547 | /// Throw FutureTimeout if this Future does not complete within the given |
1548 | /// duration from now. The optional Timekeeper is as with futures::sleep(). |
1549 | /// |
1550 | /// Preconditions: |
1551 | /// |
1552 | /// - `valid() == true` (else throws FutureInvalid) |
1553 | /// |
1554 | /// Postconditions: |
1555 | /// |
1556 | /// - Calling code should act as if `valid() == false`, |
1557 | /// i.e., as if `*this` was moved into RESULT. |
1558 | /// - `RESULT.valid() == true` |
1559 | Future<T> within(Duration dur, Timekeeper* tk = nullptr) &&; |
1560 | |
1561 | /// Throw the given exception if this Future does not complete within the |
1562 | /// given duration from now. The optional Timekeeper is as with |
1563 | /// futures::sleep(). |
1564 | /// |
1565 | /// Preconditions: |
1566 | /// |
1567 | /// - `valid() == true` (else throws FutureInvalid) |
1568 | /// |
1569 | /// Postconditions: |
1570 | /// |
1571 | /// - Calling code should act as if `valid() == false`, |
1572 | /// i.e., as if `*this` was moved into RESULT. |
1573 | /// - `RESULT.valid() == true` |
1574 | template <class E> |
1575 | Future<T> within(Duration dur, E exception, Timekeeper* tk = nullptr) &&; |
1576 | |
1577 | /// Delay the completion of this Future for at least this duration from |
1578 | /// now. The optional Timekeeper is as with futures::sleep(). |
1579 | /// |
1580 | /// Preconditions: |
1581 | /// |
1582 | /// - `valid() == true` (else throws FutureInvalid) |
1583 | /// |
1584 | /// Postconditions: |
1585 | /// |
1586 | /// - `valid() == false` |
1587 | /// - `RESULT.valid() == true` |
1588 | Future<T> delayed(Duration, Timekeeper* = nullptr) &&; |
1589 | |
1590 | /// Delay the completion of this Future for at least this duration from |
1591 | /// now. The optional Timekeeper is as with futures::sleep(). |
1592 | /// NOTE: Deprecated |
1593 | /// WARNING: Returned future may complete on Timekeeper thread. |
1594 | Future<T> delayedUnsafe(Duration, Timekeeper* = nullptr); |
1595 | |
1596 | /// Blocks until the future is fulfilled. Returns the value (moved-out), or |
1597 | /// throws the exception. The future must not already have a continuation. |
1598 | /// |
1599 | /// Preconditions: |
1600 | /// |
1601 | /// - `valid() == true` (else throws FutureInvalid) |
1602 | /// |
1603 | /// Postconditions: |
1604 | /// |
1605 | /// - `valid() == false` |
1606 | T get() &&; |
1607 | |
1608 | [[deprecated("must be rvalue-qualified, e.g., std::move(future).get()" )]] T |
1609 | get() & = delete; |
1610 | |
1611 | /// Blocks until the future is fulfilled, or until `dur` elapses. Returns the |
1612 | /// value (moved-out), or throws the exception (which might be a FutureTimeout |
1613 | /// exception). |
1614 | /// |
1615 | /// Preconditions: |
1616 | /// |
1617 | /// - `valid() == true` (else throws FutureInvalid) |
1618 | /// |
1619 | /// Postconditions: |
1620 | /// |
1621 | /// - `valid() == false` |
1622 | T get(Duration dur) &&; |
1623 | |
1624 | [[deprecated("must be rvalue-qualified, e.g., std::move(future).get(dur)" )]] T |
1625 | get(Duration dur) & = delete; |
1626 | |
1627 | /// A reference to the Try of the value |
1628 | /// |
1629 | /// Preconditions: |
1630 | /// |
1631 | /// - `valid() == true` (else throws FutureInvalid) |
1632 | /// - `isReady() == true` (else throws FutureNotReady) |
1633 | Try<T>& getTry(); |
1634 | |
1635 | /// Blocks until this Future is complete. |
1636 | /// |
1637 | /// Preconditions: |
1638 | /// |
1639 | /// - `valid() == true` (else throws FutureInvalid) |
1640 | /// |
1641 | /// Postconditions: |
1642 | /// |
1643 | /// - `valid() == true` |
1644 | /// - `&RESULT == this` |
1645 | /// - `isReady() == true` |
1646 | Future<T>& wait() &; |
1647 | |
1648 | /// Blocks until this Future is complete. |
1649 | /// |
1650 | /// Preconditions: |
1651 | /// |
1652 | /// - `valid() == true` (else throws FutureInvalid) |
1653 | /// |
1654 | /// Postconditions: |
1655 | /// |
1656 | /// - `valid() == true` (but the calling code can trivially move-out `*this` |
1657 | /// by assigning or constructing the result into a distinct object). |
1658 | /// - `&RESULT == this` |
1659 | /// - `isReady() == true` |
1660 | Future<T>&& wait() &&; |
1661 | |
1662 | /// Blocks until this Future is complete, or `dur` elapses. |
1663 | /// |
1664 | /// Preconditions: |
1665 | /// |
1666 | /// - `valid() == true` (else throws FutureInvalid) |
1667 | /// |
1668 | /// Postconditions: |
1669 | /// |
1670 | /// - `valid() == true` (so you may call `wait(...)` repeatedly) |
1671 | /// - `&RESULT == this` |
1672 | /// - `isReady()` will be indeterminate - may or may not be true |
1673 | Future<T>& wait(Duration dur) &; |
1674 | |
1675 | /// Blocks until this Future is complete or until `dur` passes. |
1676 | /// |
1677 | /// Preconditions: |
1678 | /// |
1679 | /// - `valid() == true` (else throws FutureInvalid) |
1680 | /// |
1681 | /// Postconditions: |
1682 | /// |
1683 | /// - `valid() == true` (but the calling code can trivially move-out `*this` |
1684 | /// by assigning or constructing the result into a distinct object). |
1685 | /// - `&RESULT == this` |
1686 | /// - `isReady()` will be indeterminate - may or may not be true |
1687 | Future<T>&& wait(Duration dur) &&; |
1688 | |
1689 | /// Call e->drive() repeatedly until the future is fulfilled. Examples |
1690 | /// of DrivableExecutor include EventBase and ManualExecutor. Returns a |
1691 | /// reference to this Future so that you can chain calls if desired. |
1692 | /// value (moved-out), or throws the exception. |
1693 | /// |
1694 | /// Preconditions: |
1695 | /// |
1696 | /// - `valid() == true` (else throws FutureInvalid) |
1697 | /// |
1698 | /// Postconditions: |
1699 | /// |
1700 | /// - `valid() == true` (does not move-out `*this`) |
1701 | /// - `&RESULT == this` |
1702 | Future<T>& waitVia(DrivableExecutor* e) &; |
1703 | |
1704 | /// Overload of waitVia() for rvalue Futures |
1705 | /// |
1706 | /// Preconditions: |
1707 | /// |
1708 | /// - `valid() == true` (else throws FutureInvalid) |
1709 | /// |
1710 | /// Postconditions: |
1711 | /// |
1712 | /// - `valid() == true` (but the calling code can trivially move-out `*this` |
1713 | /// by assigning or constructing the result into a distinct object). |
1714 | /// - `&RESULT == this` |
1715 | Future<T>&& waitVia(DrivableExecutor* e) &&; |
1716 | |
1717 | /// As waitVia but may return early after dur passes. |
1718 | /// |
1719 | /// Preconditions: |
1720 | /// |
1721 | /// - `valid() == true` (else throws FutureInvalid) |
1722 | /// |
1723 | /// Postconditions: |
1724 | /// |
1725 | /// - `valid() == true` (does not move-out `*this`) |
1726 | /// - `&RESULT == this` |
1727 | Future<T>& waitVia(TimedDrivableExecutor* e, Duration dur) &; |
1728 | |
1729 | /// Overload of waitVia() for rvalue Futures |
1730 | /// As waitVia but may return early after dur passes. |
1731 | /// |
1732 | /// Preconditions: |
1733 | /// |
1734 | /// - `valid() == true` (else throws FutureInvalid) |
1735 | /// |
1736 | /// Postconditions: |
1737 | /// |
1738 | /// - `valid() == true` (but the calling code can trivially move-out `*this` |
1739 | /// by assigning or constructing the result into a distinct object). |
1740 | /// - `&RESULT == this` |
1741 | Future<T>&& waitVia(TimedDrivableExecutor* e, Duration dur) &&; |
1742 | |
1743 | /// If the value in this Future is equal to the given Future, when they have |
1744 | /// both completed, the value of the resulting Future<bool> will be true. It |
1745 | /// will be false otherwise (including when one or both Futures have an |
1746 | /// exception) |
1747 | Future<bool> willEqual(Future<T>&); |
1748 | |
1749 | /// predicate behaves like std::function<bool(T const&)> |
1750 | /// If the predicate does not obtain with the value, the result |
1751 | /// is a folly::FuturePredicateDoesNotObtain exception |
1752 | /// |
1753 | /// Preconditions: |
1754 | /// |
1755 | /// - `valid() == true` (else throws FutureInvalid) |
1756 | /// |
1757 | /// Postconditions: |
1758 | /// |
1759 | /// - Calling code should act as if `valid() == false`, |
1760 | /// i.e., as if `*this` was moved into RESULT. |
1761 | /// - `RESULT.valid() == true` |
1762 | template <class F> |
1763 | Future<T> filter(F&& predicate) &&; |
1764 | |
1765 | /// Like reduce, but works on a Future<std::vector<T / Try<T>>>, for example |
1766 | /// the result of collect or collectAll |
1767 | /// |
1768 | /// Preconditions: |
1769 | /// |
1770 | /// - `valid() == true` (else throws FutureInvalid) |
1771 | /// |
1772 | /// Postconditions: |
1773 | /// |
1774 | /// - Calling code should act as if `valid() == false`, |
1775 | /// i.e., as if `*this` was moved into RESULT. |
1776 | /// - `RESULT.valid() == true` |
1777 | template <class I, class F> |
1778 | Future<I> reduce(I&& initial, F&& func) &&; |
1779 | |
1780 | /// Create a Future chain from a sequence of continuations. i.e. |
1781 | /// |
1782 | /// f.then(a).then(b).then(c) |
1783 | /// |
1784 | /// where f is a Future<A> and the result of the chain is a Future<D> |
1785 | /// becomes |
1786 | /// |
1787 | /// std::move(f).thenMulti(a, b, c); |
1788 | /// |
1789 | /// Preconditions: |
1790 | /// |
1791 | /// - `valid() == true` (else throws FutureInvalid) |
1792 | /// |
1793 | /// Postconditions: |
1794 | /// |
1795 | /// - Calling code should act as if `valid() == false`, |
1796 | /// i.e., as if `*this` was moved into RESULT. |
1797 | /// - `RESULT.valid() == true` |
1798 | template <class Callback, class... Callbacks> |
1799 | auto thenMulti(Callback&& fn, Callbacks&&... fns) && { |
1800 | // thenMulti with two callbacks is just then(a).thenMulti(b, ...) |
1801 | |
1802 | // TODO(T29171940): Switch to thenImplementation here. It is ambiguous |
1803 | // as then used to be but that is better than keeping then in the public |
1804 | // API. |
1805 | using R = futures::detail::callableResult<T, decltype(fn)>; |
1806 | return std::move(*this) |
1807 | .thenImplementation(std::forward<Callback>(fn), R{}) |
1808 | .thenMulti(std::forward<Callbacks>(fns)...); |
1809 | } |
1810 | |
1811 | /// Create a Future chain from a sequence of callbacks. |
1812 | /// |
1813 | /// Preconditions: |
1814 | /// |
1815 | /// - `valid() == true` (else throws FutureInvalid) |
1816 | /// |
1817 | /// Postconditions: |
1818 | /// |
1819 | /// - Calling code should act as if `valid() == false`, |
1820 | /// i.e., as if `*this` was moved into RESULT. |
1821 | /// - `RESULT.valid() == true` |
1822 | template <class Callback> |
1823 | auto thenMulti(Callback&& fn) && { |
1824 | // thenMulti with one callback is just a then |
1825 | |
1826 | // TODO(T29171940): Switch to thenImplementation here. It is ambiguous |
1827 | // as then used to be but that is better than keeping then in the public |
1828 | // API. |
1829 | using R = futures::detail::callableResult<T, decltype(fn)>; |
1830 | return std::move(*this).thenImplementation(std::forward<Callback>(fn), R{}); |
1831 | } |
1832 | |
1833 | template <class Callback> |
1834 | auto thenMulti(Callback&& fn) & { |
1835 | return std::move(*this).thenMulti(std::forward<Callback>(fn)); |
1836 | } |
1837 | |
1838 | /// Create a Future chain from a sequence of callbacks. i.e. |
1839 | /// |
1840 | /// f.via(executor).then(a).then(b).then(c).via(oldExecutor) |
1841 | /// |
1842 | /// where f is a Future<A> and the result of the chain is a Future<D> |
1843 | /// becomes |
1844 | /// |
1845 | /// std::move(f).thenMultiWithExecutor(executor, a, b, c); |
1846 | /// |
1847 | /// Preconditions: |
1848 | /// |
1849 | /// - `valid() == true` (else throws FutureInvalid) |
1850 | /// |
1851 | /// Postconditions: |
1852 | /// |
1853 | /// - Calling code should act as if `valid() == false`, |
1854 | /// i.e., as if `*this` was moved into RESULT. |
1855 | /// - `RESULT.valid() == true` |
1856 | template <class Callback, class... Callbacks> |
1857 | auto |
1858 | thenMultiWithExecutor(Executor* x, Callback&& fn, Callbacks&&... fns) && { |
1859 | // thenMultiExecutor with two callbacks is |
1860 | // via(x).then(a).thenMulti(b, ...).via(oldX) |
1861 | auto oldX = this->getExecutor(); |
1862 | this->setExecutor(x); |
1863 | // TODO(T29171940): Switch to thenImplementation here. It is ambiguous |
1864 | // as then used to be but that is better than keeping then in the public |
1865 | // API. |
1866 | using R = futures::detail::callableResult<T, decltype(fn)>; |
1867 | return std::move(*this) |
1868 | .thenImplementation(std::forward<Callback>(fn), R{}) |
1869 | .thenMulti(std::forward<Callbacks>(fns)...) |
1870 | .via(oldX); |
1871 | } |
1872 | |
1873 | template <class Callback> |
1874 | auto thenMultiWithExecutor(Executor* x, Callback&& fn) && { |
1875 | // thenMulti with one callback is just a then with an executor |
1876 | return std::move(*this).then(x, std::forward<Callback>(fn)); |
1877 | } |
1878 | |
1879 | /// Moves-out `*this`, creating/returning a corresponding SemiFuture. |
1880 | /// Result will behave like `*this` except result won't have an Executor. |
1881 | /// |
1882 | /// Postconditions: |
1883 | /// |
1884 | /// - `RESULT.valid() ==` the original value of `this->valid()` |
1885 | /// - RESULT will not have an Executor regardless of whether `*this` had one |
1886 | SemiFuture<T> semi() && { |
1887 | return SemiFuture<T>{std::move(*this)}; |
1888 | } |
1889 | |
1890 | #if FOLLY_HAS_COROUTINES |
1891 | |
1892 | // Overload needed to customise behaviour of awaiting a Future<T> |
1893 | // inside a folly::coro::Task coroutine. |
1894 | friend Future<T> co_viaIfAsync( |
1895 | folly::Executor* executor, |
1896 | Future<T>&& future) noexcept { |
1897 | return std::move(future).via(executor); |
1898 | } |
1899 | |
1900 | #endif |
1901 | |
1902 | protected: |
1903 | friend class Promise<T>; |
1904 | template <class> |
1905 | friend class futures::detail::FutureBase; |
1906 | template <class> |
1907 | friend class Future; |
1908 | template <class> |
1909 | friend class SemiFuture; |
1910 | template <class> |
1911 | friend class FutureSplitter; |
1912 | |
1913 | using Base::setExecutor; |
1914 | using Base::throwIfContinued; |
1915 | using Base::throwIfInvalid; |
1916 | using typename Base::Core; |
1917 | |
1918 | explicit Future(Core* obj) : Base(obj) {} |
1919 | |
1920 | explicit Future(futures::detail::EmptyConstruct) noexcept |
1921 | : Base(futures::detail::EmptyConstruct{}) {} |
1922 | |
1923 | template <class T2> |
1924 | friend Future<T2> makeFuture(Try<T2>); |
1925 | |
1926 | /// Repeat the given future (i.e., the computation it contains) n times. |
1927 | /// |
1928 | /// thunk behaves like std::function<Future<T2>(void)> |
1929 | template <class F> |
1930 | friend Future<Unit> times(int n, F&& thunk); |
1931 | |
1932 | /// Carry out the computation contained in the given future if |
1933 | /// the predicate holds. |
1934 | /// |
1935 | /// thunk behaves like std::function<Future<T2>(void)> |
1936 | template <class F> |
1937 | friend Future<Unit> when(bool p, F&& thunk); |
1938 | |
1939 | /// Carry out the computation contained in the given future if |
1940 | /// while the predicate continues to hold. |
1941 | /// |
1942 | /// thunk behaves like std::function<Future<T2>(void)> |
1943 | /// |
1944 | /// predicate behaves like std::function<bool(void)> |
1945 | template <class P, class F> |
1946 | friend Future<Unit> whileDo(P&& predicate, F&& thunk); |
1947 | |
1948 | template <class FT> |
1949 | friend void futures::detail::convertFuture( |
1950 | SemiFuture<FT>&& sf, |
1951 | Future<FT>& f); |
1952 | }; |
1953 | |
1954 | /// A Timekeeper handles the details of keeping time and fulfilling delay |
1955 | /// promises. The returned Future<Unit> will either complete after the |
1956 | /// elapsed time, or in the event of some kind of exceptional error may hold |
1957 | /// an exception. These Futures respond to cancellation. If you use a lot of |
1958 | /// Delays and many of them ultimately are unneeded (as would be the case for |
1959 | /// Delays that are used to trigger timeouts of async operations), then you |
1960 | /// can and should cancel them to reclaim resources. |
1961 | /// |
1962 | /// Users will typically get one of these via Future::sleep(Duration dur) or |
1963 | /// use them implicitly behind the scenes by passing a timeout to some Future |
1964 | /// operation. |
1965 | /// |
1966 | /// Although we don't formally alias Delay = Future<Unit>, |
1967 | /// that's an appropriate term for it. People will probably also call these |
1968 | /// Timeouts, and that's ok I guess, but that term is so overloaded I thought |
1969 | /// it made sense to introduce a cleaner term. |
1970 | /// |
1971 | /// Remember that Duration is a std::chrono duration (millisecond resolution |
1972 | /// at the time of writing). When writing code that uses specific durations, |
1973 | /// prefer using the explicit std::chrono type, e.g. std::chrono::milliseconds |
1974 | /// over Duration. This makes the code more legible and means you won't be |
1975 | /// unpleasantly surprised if we redefine Duration to microseconds, or |
1976 | /// something. |
1977 | /// |
1978 | /// timekeeper.after(std::chrono::duration_cast<Duration>(someNanoseconds)) |
1979 | class Timekeeper { |
1980 | public: |
1981 | virtual ~Timekeeper() = default; |
1982 | |
1983 | /// Returns a future that will complete after the given duration with the |
1984 | /// elapsed time. Exceptional errors can happen but they must be |
1985 | /// exceptional. Use the steady (monotonic) clock. |
1986 | /// |
1987 | /// The consumer thread may cancel this Future to reclaim resources. |
1988 | /// |
1989 | /// This future probably completes on the timer thread. You should almost |
1990 | /// certainly follow it with a via() call or the accuracy of other timers |
1991 | /// will suffer. |
1992 | virtual Future<Unit> after(Duration dur) = 0; |
1993 | |
1994 | /// Returns a future that will complete at the requested time. |
1995 | /// |
1996 | /// You may cancel this Future to reclaim resources. |
1997 | /// |
1998 | /// NB This is sugar for `after(when - now)`, so while you are welcome to |
1999 | /// use a std::chrono::system_clock::time_point it will not track changes to |
2000 | /// the system clock but rather execute that many milliseconds in the future |
2001 | /// according to the steady clock. |
2002 | template <class Clock> |
2003 | Future<Unit> at(std::chrono::time_point<Clock> when); |
2004 | }; |
2005 | |
2006 | template <class T> |
2007 | std::pair<Promise<T>, Future<T>> makePromiseContract(Executor* e) { |
2008 | auto p = Promise<T>(); |
2009 | auto f = p.getSemiFuture().via(e); |
2010 | return std::make_pair(std::move(p), std::move(f)); |
2011 | } |
2012 | |
2013 | } // namespace folly |
2014 | |
2015 | #if FOLLY_HAS_COROUTINES |
2016 | |
2017 | namespace folly { |
2018 | namespace detail { |
2019 | |
2020 | template <typename T> |
2021 | class FutureAwaitable { |
2022 | public: |
2023 | explicit FutureAwaitable(folly::Future<T>&& future) noexcept |
2024 | : future_(std::move(future)) {} |
2025 | |
2026 | bool await_ready() const { |
2027 | return future_.isReady(); |
2028 | } |
2029 | |
2030 | T await_resume() { |
2031 | return std::move(future_).value(); |
2032 | } |
2033 | |
2034 | void await_suspend(std::experimental::coroutine_handle<> h) { |
2035 | future_.setCallback_([h](Try<T>&&) mutable { |
2036 | // Don't std::move() so the try is left in the future for await_resume() |
2037 | h.resume(); |
2038 | }); |
2039 | } |
2040 | |
2041 | private: |
2042 | folly::Future<T> future_; |
2043 | }; |
2044 | |
2045 | } // namespace detail |
2046 | |
2047 | template <typename T> |
2048 | inline detail::FutureAwaitable<T> |
2049 | /* implicit */ operator co_await(Future<T>&& future) noexcept { |
2050 | return detail::FutureAwaitable<T>(std::move(future)); |
2051 | } |
2052 | |
2053 | } // namespace folly |
2054 | #endif |
2055 | |
2056 | #include <folly/futures/Future-inl.h> |
2057 | |