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