57f8636b8babaea859402bc9b3924d35a50c3650
[folly.git] / folly / wangle / Future.h
1 /*
2  * Copyright 2014 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
17 #pragma once
18
19 #include <algorithm>
20 #include <exception>
21 #include <functional>
22 #include <memory>
23 #include <type_traits>
24 #include <vector>
25
26 #include <folly/MoveWrapper.h>
27 #include <folly/wangle/Promise.h>
28 #include <folly/wangle/Try.h>
29
30 namespace folly { namespace wangle {
31
32 namespace detail {
33   template <class> struct Core;
34   template <class...> struct VariadicContext;
35
36   template <class T>
37   struct AliasIfVoid {
38     typedef typename std::conditional<
39       std::is_same<T, void>::value,
40       int,
41       T>::type type;
42   };
43 }
44
45 template <class> struct Promise;
46
47 template <typename T> struct isFuture;
48
49 template <class T>
50 class Future {
51  public:
52   typedef T value_type;
53
54   // not copyable
55   Future(Future const&) = delete;
56   Future& operator=(Future const&) = delete;
57
58   // movable
59   Future(Future&&) noexcept;
60   Future& operator=(Future&&);
61
62   ~Future();
63
64   /** Return the reference to result. Should not be called if !isReady().
65     Will rethrow the exception if an exception has been
66     captured.
67
68     This function is not thread safe - the returned Future can only
69     be executed from the thread that the executor runs it in.
70     See below for a thread safe version
71     */
72   typename std::add_lvalue_reference<T>::type
73   value();
74   typename std::add_lvalue_reference<const T>::type
75   value() const;
76
77   /// Returns an inactive Future which will call back on the other side of
78   /// executor (when it is activated).
79   ///
80   /// NB remember that Futures activate when they destruct. This is good,
81   /// it means that this will work:
82   ///
83   ///   f.via(e).then(a).then(b);
84   ///
85   /// a and b will execute in the same context (the far side of e), because
86   /// the Future (temporary variable) created by via(e) does not call back
87   /// until it destructs, which is after then(a) and then(b) have been wired
88   /// up.
89   ///
90   /// But this is still racy:
91   ///
92   ///   f = f.via(e).then(a);
93   ///   f.then(b);
94   template <typename Executor>
95   Future<T> via(Executor* executor);
96
97   /** True when the result (or exception) is ready. */
98   bool isReady() const;
99
100   /** A reference to the Try of the value */
101   Try<T>& getTry();
102
103   /** When this Future has completed, execute func which is a function that
104     takes a Try<T>&&. A Future for the return type of func is
105     returned. e.g.
106
107     Future<string> f2 = f1.then([](Try<T>&&) { return string("foo"); });
108
109     The Future given to the functor is ready, and the functor may call
110     value(), which may rethrow if this has captured an exception. If func
111     throws, the exception will be captured in the Future that is returned.
112     */
113   /* TODO n3428 and other async frameworks have something like then(scheduler,
114      Future), we might want to support a similar API which could be
115      implemented a little more efficiently than
116      f.via(executor).then(callback) */
117   template <class F>
118   typename std::enable_if<
119     !isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
120     Future<typename std::result_of<F(Try<T>&&)>::type> >::type
121   then(F&& func);
122
123   /// Variant where func takes a T directly, bypassing a try. Any exceptions
124   /// will be implicitly passed on to the resultant Future.
125   ///
126   ///   Future<int> f = makeFuture<int>(42).then([](int i) { return i+1; });
127   template <class F>
128   typename std::enable_if<
129     !std::is_same<T, void>::value &&
130     !isFuture<typename std::result_of<
131       F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
132     Future<typename std::result_of<
133       F(typename detail::AliasIfVoid<T>::type&&)>::type> >::type
134   then(F&& func);
135
136   /// Like the above variant, but for void futures. That is, func takes no
137   /// argument.
138   ///
139   ///   Future<int> f = makeFuture().then([] { return 42; });
140   template <class F>
141   typename std::enable_if<
142     std::is_same<T, void>::value &&
143     !isFuture<typename std::result_of<F()>::type>::value,
144     Future<typename std::result_of<F()>::type> >::type
145   then(F&& func);
146
147   /// Variant where func returns a Future<T> instead of a T. e.g.
148   ///
149   ///   Future<string> f2 = f1.then(
150   ///     [](Try<T>&&) { return makeFuture<string>("foo"); });
151   template <class F>
152   typename std::enable_if<
153     isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
154     Future<typename std::result_of<F(Try<T>&&)>::type::value_type> >::type
155   then(F&& func);
156
157   /// Variant where func returns a Future<T2> and takes a T directly, bypassing
158   /// a Try. Any exceptions will be implicitly passed on to the resultant
159   /// Future. For example,
160   ///
161   ///   Future<int> f = makeFuture<int>(42).then(
162   ///     [](int i) { return makeFuture<int>(i+1); });
163   template <class F>
164   typename std::enable_if<
165     !std::is_same<T, void>::value &&
166     isFuture<typename std::result_of<
167       F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
168     Future<typename std::result_of<
169       F(typename detail::AliasIfVoid<T>::type&&)>::type::value_type> >::type
170   then(F&& func);
171
172   /// Like the above variant, but for void futures. That is, func takes no
173   /// argument and returns a future.
174   ///
175   ///   Future<int> f = makeFuture().then(
176   ///     [] { return makeFuture<int>(42); });
177   template <class F>
178   typename std::enable_if<
179     std::is_same<T, void>::value &&
180     isFuture<typename std::result_of<F()>::type>::value,
181     Future<typename std::result_of<F()>::type::value_type> >::type
182   then(F&& func);
183
184   /// Variant where func is an ordinary function (static method, method)
185   ///
186   ///   R doWork(Try<T>&&);
187   ///
188   ///   Future<R> f2 = f1.then(doWork);
189   ///
190   /// or
191   ///
192   ///   struct Worker {
193   ///     static R doWork(Try<T>&&); }
194   ///
195   ///   Future<R> f2 = f1.then(&Worker::doWork);
196   template <class = T, class R = std::nullptr_t>
197   typename std::enable_if<!isFuture<R>::value, Future<R>>::type
198   inline then(R(*func)(Try<T>&&)) {
199     return then([func](Try<T>&& t) {
200       return (*func)(std::move(t));
201     });
202   }
203
204   /// Variant where func returns a Future<R> instead of a R. e.g.
205   ///
206   ///   struct Worker {
207   ///     Future<R> doWork(Try<T>&&); }
208   ///
209   ///   Future<R> f2 = f1.then(&Worker::doWork);
210   template <class = T, class R = std::nullptr_t>
211   typename std::enable_if<isFuture<R>::value, R>::type
212   inline then(R(*func)(Try<T>&&)) {
213     return then([func](Try<T>&& t) {
214       return (*func)(std::move(t));
215     });
216   }
217
218   /// Variant where func is an member function
219   ///
220   ///   struct Worker {
221   ///     R doWork(Try<T>&&); }
222   ///
223   ///   Worker *w;
224   ///   Future<R> f2 = f1.then(w, &Worker::doWork);
225   template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
226   typename std::enable_if<!isFuture<R>::value, Future<R>>::type
227   inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
228     return then([instance, func](Try<T>&& t) {
229       return (instance->*func)(std::move(t));
230     });
231   }
232
233   // Same as above, but func takes void instead of Try<void>&&
234   template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
235   typename std::enable_if<
236       std::is_same<T, void>::value && !isFuture<R>::value, Future<R>>::type
237   inline then(Caller *instance, R(Caller::*func)()) {
238     return then([instance, func]() {
239       return (instance->*func)();
240     });
241   }
242
243   // Same as above, but func takes T&& instead of Try<T>&&
244   template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
245   typename std::enable_if<
246       !std::is_same<T, void>::value && !isFuture<R>::value, Future<R>>::type
247   inline then(
248       Caller *instance,
249       R(Caller::*func)(typename detail::AliasIfVoid<T>::type&&)) {
250     return then([instance, func](T&& t) {
251       return (instance->*func)(std::move(t));
252     });
253   }
254
255   /// Variant where func returns a Future<R> instead of a R. e.g.
256   ///
257   ///   struct Worker {
258   ///     Future<R> doWork(Try<T>&&); }
259   ///
260   ///   Worker *w;
261   ///   Future<R> f2 = f1.then(w, &Worker::doWork);
262   template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
263   typename std::enable_if<isFuture<R>::value, R>::type
264   inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
265     return then([instance, func](Try<T>&& t) {
266       return (instance->*func)(std::move(t));
267     });
268   }
269
270   // Same as above, but func takes void instead of Try<void>&&
271   template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
272   typename std::enable_if<
273       std::is_same<T, void>::value && isFuture<R>::value, R>::type
274   inline then(Caller *instance, R(Caller::*func)()) {
275     return then([instance, func]() {
276       return (instance->*func)();
277     });
278   }
279
280   // Same as above, but func takes T&& instead of Try<T>&&
281   template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
282   typename std::enable_if<
283       !std::is_same<T, void>::value && isFuture<R>::value, R>::type
284   inline then(
285       Caller *instance,
286       R(Caller::*func)(typename detail::AliasIfVoid<T>::type&&)) {
287     return then([instance, func](T&& t) {
288       return (instance->*func)(std::move(t));
289     });
290   }
291
292   /// Convenience method for ignoring the value and creating a Future<void>.
293   /// Exceptions still propagate.
294   Future<void> then();
295
296   /// This is not the method you're looking for.
297   ///
298   /// This needs to be public because it's used by make* and when*, and it's
299   /// not worth listing all those and their fancy template signatures as
300   /// friends. But it's not for public consumption.
301   template <class F>
302   void setCallback_(F&& func);
303
304   /// A Future's callback is executed when all three of these conditions have
305   /// become true: it has a value (set by the Promise), it has a callback (set
306   /// by then), and it is active (active by default).
307   ///
308   /// Inactive Futures will activate upon destruction.
309   Future<T>& activate() & {
310     core_->activate();
311     return *this;
312   }
313   Future<T>& deactivate() & {
314     core_->deactivate();
315     return *this;
316   }
317   Future<T> activate() && {
318     core_->activate();
319     return std::move(*this);
320   }
321   Future<T> deactivate() && {
322     core_->deactivate();
323     return std::move(*this);
324   }
325   bool isActive() {
326     return core_->isActive();
327   }
328
329   template <class E>
330   void raise(E&& exception) {
331     raise(std::make_exception_ptr(std::forward<E>(exception)));
332   }
333
334   /// Raise an interrupt. If the promise holder has an interrupt
335   /// handler it will be called and potentially stop asynchronous work from
336   /// being done. This is advisory only - a promise holder may not set an
337   /// interrupt handler, or may do anything including ignore. But, if you know
338   /// your future supports this the most likely result is stopping or
339   /// preventing the asynchronous operation (if in time), and the promise
340   /// holder setting an exception on the future. (That may happen
341   /// asynchronously, of course.)
342   void raise(std::exception_ptr interrupt);
343
344   void cancel() {
345     raise(FutureCancellation());
346   }
347
348  private:
349   typedef detail::Core<T>* corePtr;
350
351   // shared core state object
352   corePtr core_;
353
354   explicit
355   Future(corePtr obj) : core_(obj) {}
356
357   void detach();
358
359   void throwIfInvalid() const;
360
361   friend class Promise<T>;
362 };
363
364 /**
365   Make a completed Future by moving in a value. e.g.
366
367     string foo = "foo";
368     auto f = makeFuture(std::move(foo));
369
370   or
371
372     auto f = makeFuture<string>("foo");
373 */
374 template <class T>
375 Future<typename std::decay<T>::type> makeFuture(T&& t);
376
377 /** Make a completed void Future. */
378 Future<void> makeFuture();
379
380 /** Make a completed Future by executing a function. If the function throws
381   we capture the exception, otherwise we capture the result. */
382 template <class F>
383 auto makeFutureTry(
384   F&& func,
385   typename std::enable_if<
386     !std::is_reference<F>::value, bool>::type sdf = false)
387   -> Future<decltype(func())>;
388
389 template <class F>
390 auto makeFutureTry(
391   F const& func)
392   -> Future<decltype(func())>;
393
394 /// Make a failed Future from an exception_ptr.
395 /// Because the Future's type cannot be inferred you have to specify it, e.g.
396 ///
397 ///   auto f = makeFuture<string>(std::current_exception());
398 template <class T>
399 Future<T> makeFuture(std::exception_ptr const& e);
400
401 /** Make a Future from an exception type E that can be passed to
402   std::make_exception_ptr(). */
403 template <class T, class E>
404 typename std::enable_if<std::is_base_of<std::exception, E>::value,
405                         Future<T>>::type
406 makeFuture(E const& e);
407
408 /** Make a Future out of a Try */
409 template <class T>
410 Future<T> makeFuture(Try<T>&& t);
411
412 /*
413  * Return a new Future that will call back on the given Executor.
414  * This is just syntactic sugar for makeFuture().via(executor)
415  *
416  * @param executor the Executor to call back on
417  *
418  * @returns a void Future that will call back on the given executor
419  */
420 template <typename Executor>
421 Future<void> via(Executor* executor);
422
423 /** When all the input Futures complete, the returned Future will complete.
424   Errors do not cause early termination; this Future will always succeed
425   after all its Futures have finished (whether successfully or with an
426   error).
427
428   The Futures are moved in, so your copies are invalid. If you need to
429   chain further from these Futures, use the variant with an output iterator.
430
431   XXX is this still true?
432   This function is thread-safe for Futures running on different threads.
433
434   The return type for Future<T> input is a Future<std::vector<Try<T>>>
435   */
436 template <class InputIterator>
437 Future<std::vector<Try<
438   typename std::iterator_traits<InputIterator>::value_type::value_type>>>
439 whenAll(InputIterator first, InputIterator last);
440
441 /// This version takes a varying number of Futures instead of an iterator.
442 /// The return type for (Future<T1>, Future<T2>, ...) input
443 /// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>.
444 /// The Futures are moved in, so your copies are invalid.
445 template <typename... Fs>
446 typename detail::VariadicContext<
447   typename std::decay<Fs>::type::value_type...>::type
448 whenAll(Fs&&... fs);
449
450 /** The result is a pair of the index of the first Future to complete and
451   the Try. If multiple Futures complete at the same time (or are already
452   complete when passed in), the "winner" is chosen non-deterministically.
453
454   This function is thread-safe for Futures running on different threads.
455   */
456 template <class InputIterator>
457 Future<std::pair<
458   size_t,
459   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
460 whenAny(InputIterator first, InputIterator last);
461
462 /** when n Futures have completed, the Future completes with a vector of
463   the index and Try of those n Futures (the indices refer to the original
464   order, but the result vector will be in an arbitrary order)
465
466   Not thread safe.
467   */
468 template <class InputIterator>
469 Future<std::vector<std::pair<
470   size_t,
471   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
472 whenN(InputIterator first, InputIterator last, size_t n);
473
474 /** Wait for the given future to complete on a semaphore. Returns a completed
475  * future containing the result.
476  *
477  * NB if the promise for the future would be fulfilled in the same thread that
478  * you call this, it will deadlock.
479  */
480 template <class T>
481 Future<T> waitWithSemaphore(Future<T>&& f);
482
483 /** Wait for up to `timeout` for the given future to complete. Returns a future
484  * which may or may not be completed depending whether the given future
485  * completed in time
486  *
487  * Note: each call to this starts a (short-lived) thread and allocates memory.
488  */
489 template <typename T, class Duration>
490 Future<T> waitWithSemaphore(Future<T>&& f, Duration timeout);
491
492 }} // folly::wangle
493
494 #include <folly/wangle/Future-inl.h>