Fix copyright lines
[folly.git] / folly / futures / helpers.h
1 /*
2  * Copyright 2015-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 <atomic>
19 #include <tuple>
20 #include <utility>
21
22 #include <folly/Portability.h>
23 #include <folly/Try.h>
24 #include <folly/futures/Future.h>
25 #include <folly/futures/Promise.h>
26
27 namespace folly {
28
29 namespace futures {
30 namespace detail {
31 template <typename... Ts>
32 struct CollectAllVariadicContext {
33   CollectAllVariadicContext() {}
34   template <typename T, size_t I>
35   inline void setPartialResult(Try<T>& t) {
36     std::get<I>(results) = std::move(t);
37   }
38   ~CollectAllVariadicContext() {
39     p.setValue(std::move(results));
40   }
41   Promise<std::tuple<Try<Ts>...>> p;
42   std::tuple<Try<Ts>...> results;
43   typedef Future<std::tuple<Try<Ts>...>> type;
44 };
45
46 template <typename... Ts>
47 struct CollectVariadicContext {
48   CollectVariadicContext() {}
49   template <typename T, size_t I>
50   inline void setPartialResult(Try<T>& t) {
51     if (t.hasException()) {
52       if (!threw.exchange(true)) {
53         p.setException(std::move(t.exception()));
54       }
55     } else if (!threw) {
56       std::get<I>(results) = std::move(t);
57     }
58   }
59   ~CollectVariadicContext() noexcept {
60     if (!threw.exchange(true)) {
61       p.setValue(unwrapTryTuple(std::move(results)));
62     }
63   }
64   Promise<std::tuple<Ts...>> p;
65   std::tuple<folly::Try<Ts>...> results;
66   std::atomic<bool> threw{false};
67   typedef Future<std::tuple<Ts...>> type;
68 };
69 } // namespace detail
70 } // namespace futures
71
72 /// This namespace is for utility functions that would usually be static
73 /// members of Future, except they don't make sense there because they don't
74 /// depend on the template type (rather, on the type of their arguments in
75 /// some cases). This is the least-bad naming scheme we could think of. Some
76 /// of the functions herein have really-likely-to-collide names, like "map"
77 /// and "sleep".
78 namespace futures {
79   /// Returns a Future that will complete after the specified duration. The
80   /// Duration typedef of a `std::chrono` duration type indicates the
81   /// resolution you can expect to be meaningful (milliseconds at the time of
82   /// writing). Normally you wouldn't need to specify a Timekeeper, we will
83   /// use the global futures timekeeper (we run a thread whose job it is to
84   /// keep time for futures timeouts) but we provide the option for power
85   /// users.
86   ///
87   /// The Timekeeper thread will be lazily created the first time it is
88   /// needed. If your program never uses any timeouts or other time-based
89   /// Futures you will pay no Timekeeper thread overhead.
90   Future<Unit> sleep(Duration, Timekeeper* = nullptr);
91
92   /**
93    * Set func as the callback for each input Future and return a vector of
94    * Futures containing the results in the input order.
95    */
96   template <
97       class It,
98       class F,
99       class ItT = typename std::iterator_traits<It>::value_type,
100       class Result = typename decltype(
101           std::declval<ItT>().then(std::declval<F>()))::value_type>
102   std::vector<Future<Result>> map(It first, It last, F func);
103
104   // Sugar for the most common case
105   template <class Collection, class F>
106   auto map(Collection&& c, F&& func)
107       -> decltype(map(c.begin(), c.end(), func)) {
108     return map(c.begin(), c.end(), std::forward<F>(func));
109   }
110
111 } // namespace futures
112
113 /**
114   Make a completed SemiFuture by moving in a value. e.g.
115
116     string foo = "foo";
117     auto f = makeSemiFuture(std::move(foo));
118
119   or
120
121     auto f = makeSemiFuture<string>("foo");
122 */
123 template <class T>
124 SemiFuture<typename std::decay<T>::type> makeSemiFuture(T&& t);
125
126 /** Make a completed void SemiFuture. */
127 SemiFuture<Unit> makeSemiFuture();
128
129 /**
130   Make a SemiFuture by executing a function.
131
132   If the function returns a value of type T, makeSemiFutureWith
133   returns a completed SemiFuture<T>, capturing the value returned
134   by the function.
135
136   If the function returns a SemiFuture<T> already, makeSemiFutureWith
137   returns just that.
138
139   Either way, if the function throws, a failed Future is
140   returned that captures the exception.
141 */
142
143 // makeSemiFutureWith(SemiFuture<T>()) -> SemiFuture<T>
144 template <class F>
145 typename std::enable_if<isSemiFuture<typename std::result_of<F()>::type>::value,
146                         typename std::result_of<F()>::type>::type
147 makeSemiFutureWith(F&& func);
148
149 // makeSemiFutureWith(T()) -> SemiFuture<T>
150 // makeSemiFutureWith(void()) -> SemiFuture<Unit>
151 template <class F>
152 typename std::enable_if<
153     !(isSemiFuture<typename std::result_of<F()>::type>::value),
154     SemiFuture<typename Unit::Lift<typename std::result_of<F()>::type>::type>>::type
155 makeSemiFutureWith(F&& func);
156
157 /// Make a failed Future from an exception_ptr.
158 /// Because the Future's type cannot be inferred you have to specify it, e.g.
159 ///
160 ///   auto f = makeSemiFuture<string>(std::current_exception());
161 template <class T>
162 FOLLY_DEPRECATED("use makeSemiFuture(exception_wrapper)")
163 SemiFuture<T> makeSemiFuture(std::exception_ptr const& e);
164
165 /// Make a failed SemiFuture from an exception_wrapper.
166 template <class T>
167 SemiFuture<T> makeSemiFuture(exception_wrapper ew);
168
169 /** Make a SemiFuture from an exception type E that can be passed to
170   std::make_exception_ptr(). */
171 template <class T, class E>
172 typename std::enable_if<std::is_base_of<std::exception, E>::value,
173                         SemiFuture<T>>::type
174 makeSemiFuture(E const& e);
175
176 /** Make a Future out of a Try */
177 template <class T>
178 SemiFuture<T> makeSemiFuture(Try<T>&& t);
179
180 /**
181   Make a completed Future by moving in a value. e.g.
182
183     string foo = "foo";
184     auto f = makeFuture(std::move(foo));
185
186   or
187
188     auto f = makeFuture<string>("foo");
189
190   NOTE: This function is deprecated. Please use makeSemiFuture and pass the
191        appropriate executor to .via on the returned SemiFuture to get a
192        valid Future where necessary.
193 */
194 template <class T>
195 Future<typename std::decay<T>::type> makeFuture(T&& t);
196
197 /**
198   Make a completed void Future.
199
200   NOTE: This function is deprecated. Please use makeSemiFuture and pass the
201        appropriate executor to .via on the returned SemiFuture to get a
202        valid Future where necessary.
203  */
204 Future<Unit> makeFuture();
205
206 /**
207   Make a Future by executing a function.
208
209   If the function returns a value of type T, makeFutureWith
210   returns a completed Future<T>, capturing the value returned
211   by the function.
212
213   If the function returns a Future<T> already, makeFutureWith
214   returns just that.
215
216   Either way, if the function throws, a failed Future is
217   returned that captures the exception.
218
219   Calling makeFutureWith(func) is equivalent to calling
220   makeFuture().then(func).
221
222   NOTE: This function is deprecated. Please use makeSemiFutureWith and pass the
223        appropriate executor to .via on the returned SemiFuture to get a
224        valid Future where necessary.
225 */
226
227 // makeFutureWith(Future<T>()) -> Future<T>
228 template <class F>
229 typename std::enable_if<isFuture<typename std::result_of<F()>::type>::value,
230                         typename std::result_of<F()>::type>::type
231 makeFutureWith(F&& func);
232
233 // makeFutureWith(T()) -> Future<T>
234 // makeFutureWith(void()) -> Future<Unit>
235 template <class F>
236 typename std::enable_if<
237     !(isFuture<typename std::result_of<F()>::type>::value),
238     Future<typename Unit::Lift<typename std::result_of<F()>::type>::type>>::type
239 makeFutureWith(F&& func);
240
241 /// Make a failed Future from an exception_ptr.
242 /// Because the Future's type cannot be inferred you have to specify it, e.g.
243 ///
244 ///   auto f = makeFuture<string>(std::current_exception());
245 template <class T>
246 FOLLY_DEPRECATED("use makeSemiFuture(exception_wrapper)")
247 Future<T> makeFuture(std::exception_ptr const& e);
248
249 /// Make a failed Future from an exception_wrapper.
250 /// NOTE: This function is deprecated. Please use makeSemiFuture and pass the
251 ///     appropriate executor to .via on the returned SemiFuture to get a
252 ///     valid Future where necessary.
253 template <class T>
254 Future<T> makeFuture(exception_wrapper ew);
255
256 /** Make a Future from an exception type E that can be passed to
257   std::make_exception_ptr().
258
259   NOTE: This function is deprecated. Please use makeSemiFuture and pass the
260        appropriate executor to .via on the returned SemiFuture to get a
261        valid Future where necessary.
262  */
263 template <class T, class E>
264 typename std::enable_if<std::is_base_of<std::exception, E>::value,
265                         Future<T>>::type
266 makeFuture(E const& e);
267
268 /**
269   Make a Future out of a Try
270
271   NOTE: This function is deprecated. Please use makeSemiFuture and pass the
272        appropriate executor to .via on the returned SemiFuture to get a
273        valid Future where necessary.
274  */
275 template <class T>
276 Future<T> makeFuture(Try<T>&& t);
277
278 /*
279  * Return a new Future that will call back on the given Executor.
280  * This is just syntactic sugar for makeFuture().via(executor)
281  *
282  * @param executor the Executor to call back on
283  * @param priority optionally, the priority to add with. Defaults to 0 which
284  * represents medium priority.
285  *
286  * @returns a void Future that will call back on the given executor
287  */
288 inline Future<Unit> via(
289     Executor* executor,
290     int8_t priority = Executor::MID_PRI);
291
292 /// Execute a function via the given executor and return a future.
293 /// This is semantically equivalent to via(executor).then(func), but
294 /// easier to read and slightly more efficient.
295 template <class Func>
296 auto via(Executor*, Func&& func)
297     -> Future<typename isFuture<decltype(std::declval<Func>()())>::Inner>;
298
299 /** When all the input Futures complete, the returned Future will complete.
300   Errors do not cause early termination; this Future will always succeed
301   after all its Futures have finished (whether successfully or with an
302   error).
303
304   The Futures are moved in, so your copies are invalid. If you need to
305   chain further from these Futures, use the variant with an output iterator.
306
307   This function is thread-safe for Futures running on different threads. But
308   if you are doing anything non-trivial after, you will probably want to
309   follow with `via(executor)` because it will complete in whichever thread the
310   last Future completes in.
311
312   The return type for Future<T> input is a Future<std::vector<Try<T>>>
313   */
314 template <class InputIterator>
315 Future<std::vector<Try<
316   typename std::iterator_traits<InputIterator>::value_type::value_type>>>
317 collectAll(InputIterator first, InputIterator last);
318
319 /// Sugar for the most common case
320 template <class Collection>
321 auto collectAll(Collection&& c) -> decltype(collectAll(c.begin(), c.end())) {
322   return collectAll(c.begin(), c.end());
323 }
324
325 /// This version takes a varying number of Futures instead of an iterator.
326 /// The return type for (Future<T1>, Future<T2>, ...) input
327 /// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>.
328 /// The Futures are moved in, so your copies are invalid.
329 template <typename... Fs>
330 typename futures::detail::CollectAllVariadicContext<
331     typename std::decay<Fs>::type::value_type...>::type
332 collectAll(Fs&&... fs);
333
334 /// Like collectAll, but will short circuit on the first exception. Thus, the
335 /// type of the returned Future is std::vector<T> instead of
336 /// std::vector<Try<T>>
337 template <class InputIterator>
338 Future<typename futures::detail::CollectContext<typename std::iterator_traits<
339     InputIterator>::value_type::value_type>::result_type>
340 collect(InputIterator first, InputIterator last);
341
342 /// Sugar for the most common case
343 template <class Collection>
344 auto collect(Collection&& c) -> decltype(collect(c.begin(), c.end())) {
345   return collect(c.begin(), c.end());
346 }
347
348 /// Like collectAll, but will short circuit on the first exception. Thus, the
349 /// type of the returned Future is std::tuple<T1, T2, ...> instead of
350 /// std::tuple<Try<T1>, Try<T2>, ...>
351 template <typename... Fs>
352 typename futures::detail::CollectVariadicContext<
353     typename std::decay<Fs>::type::value_type...>::type
354 collect(Fs&&... fs);
355
356 /** The result is a pair of the index of the first Future to complete and
357   the Try. If multiple Futures complete at the same time (or are already
358   complete when passed in), the "winner" is chosen non-deterministically.
359
360   This function is thread-safe for Futures running on different threads.
361   */
362 template <class InputIterator>
363 Future<std::pair<
364   size_t,
365   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
366 collectAny(InputIterator first, InputIterator last);
367
368 /// Sugar for the most common case
369 template <class Collection>
370 auto collectAny(Collection&& c) -> decltype(collectAny(c.begin(), c.end())) {
371   return collectAny(c.begin(), c.end());
372 }
373
374 /** Similar to collectAny, collectAnyWithoutException return the first Future to
375  * complete without exceptions. If none of the future complete without
376  * excpetions, the last exception will be returned as a result.
377   */
378 template <class InputIterator>
379 Future<std::pair<
380     size_t,
381     typename std::iterator_traits<InputIterator>::value_type::value_type>>
382 collectAnyWithoutException(InputIterator first, InputIterator last);
383
384 /// Sugar for the most common case
385 template <class Collection>
386 auto collectAnyWithoutException(Collection&& c)
387     -> decltype(collectAnyWithoutException(c.begin(), c.end())) {
388   return collectAnyWithoutException(c.begin(), c.end());
389 }
390
391 /** when n Futures have completed, the Future completes with a vector of
392   the index and Try of those n Futures (the indices refer to the original
393   order, but the result vector will be in an arbitrary order)
394
395   Not thread safe.
396   */
397 template <class InputIterator>
398 Future<std::vector<std::pair<
399   size_t,
400   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
401 collectN(InputIterator first, InputIterator last, size_t n);
402
403 /// Sugar for the most common case
404 template <class Collection>
405 auto collectN(Collection&& c, size_t n)
406     -> decltype(collectN(c.begin(), c.end(), n)) {
407   return collectN(c.begin(), c.end(), n);
408 }
409
410 /** window creates up to n Futures using the values
411     in the collection, and then another Future for each Future
412     that completes
413
414     this is basically a sliding window of Futures of size n
415
416     func must return a Future for each value in input
417   */
418 template <
419     class Collection,
420     class F,
421     class ItT = typename std::iterator_traits<
422         typename Collection::iterator>::value_type,
423     class Result = typename futures::detail::resultOf<F, ItT&&>::value_type>
424 std::vector<Future<Result>> window(Collection input, F func, size_t n);
425
426 template <
427     class Collection,
428     class F,
429     class ItT = typename std::iterator_traits<
430         typename Collection::iterator>::value_type,
431     class Result = typename futures::detail::resultOf<F, ItT&&>::value_type>
432 std::vector<Future<Result>>
433 window(Executor* executor, Collection input, F func, size_t n);
434
435 template <typename F, typename T, typename ItT>
436 using MaybeTryArg = typename std::conditional<
437     futures::detail::callableWith<F, T&&, Try<ItT>&&>::value,
438     Try<ItT>,
439     ItT>::type;
440
441 template <typename F, typename T, typename Arg>
442 using isFutureResult = isFuture<typename std::result_of<F(T&&, Arg&&)>::type>;
443
444 /** repeatedly calls func on every result, e.g.
445     reduce(reduce(reduce(T initial, result of first), result of second), ...)
446
447     The type of the final result is a Future of the type of the initial value.
448
449     Func can either return a T, or a Future<T>
450
451     func is called in order of the input, see unorderedReduce if that is not
452     a requirement
453   */
454 template <class It, class T, class F>
455 Future<T> reduce(It first, It last, T&& initial, F&& func);
456
457 /// Sugar for the most common case
458 template <class Collection, class T, class F>
459 auto reduce(Collection&& c, T&& initial, F&& func)
460     -> decltype(reduce(c.begin(), c.end(), std::forward<T>(initial),
461                 std::forward<F>(func))) {
462   return reduce(
463       c.begin(),
464       c.end(),
465       std::forward<T>(initial),
466       std::forward<F>(func));
467 }
468
469 /** like reduce, but calls func on finished futures as they complete
470     does NOT keep the order of the input
471   */
472 template <
473     class It,
474     class T,
475     class F,
476     class ItT = typename std::iterator_traits<It>::value_type::value_type,
477     class Arg = MaybeTryArg<F, T, ItT>>
478 Future<T> unorderedReduce(It first, It last, T initial, F func);
479
480 /// Sugar for the most common case
481 template <class Collection, class T, class F>
482 auto unorderedReduce(Collection&& c, T&& initial, F&& func)
483     -> decltype(unorderedReduce(c.begin(), c.end(), std::forward<T>(initial),
484                 std::forward<F>(func))) {
485   return unorderedReduce(
486       c.begin(),
487       c.end(),
488       std::forward<T>(initial),
489       std::forward<F>(func));
490 }
491 } // namespace folly