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