2 * Copyright 2016 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <folly/futures/detail/Types.h>
20 #include <folly/Unit.h>
24 template <class> class Future;
26 /// A Timekeeper handles the details of keeping time and fulfilling delay
27 /// promises. The returned Future<Unit> will either complete after the
28 /// elapsed time, or in the event of some kind of exceptional error may hold
29 /// an exception. These Futures respond to cancellation. If you use a lot of
30 /// Delays and many of them ultimately are unneeded (as would be the case for
31 /// Delays that are used to trigger timeouts of async operations), then you
32 /// can and should cancel them to reclaim resources.
34 /// Users will typically get one of these via Future::sleep(Duration) or
35 /// use them implicitly behind the scenes by passing a timeout to some Future
38 /// Although we don't formally alias Delay = Future<Unit>,
39 /// that's an appropriate term for it. People will probably also call these
40 /// Timeouts, and that's ok I guess, but that term is so overloaded I thought
41 /// it made sense to introduce a cleaner term.
43 /// Remember that Duration is a std::chrono duration (millisecond resolution
44 /// at the time of writing). When writing code that uses specific durations,
45 /// prefer using the explicit std::chrono type, e.g. std::chrono::milliseconds
46 /// over Duration. This makes the code more legible and means you won't be
47 /// unpleasantly surprised if we redefine Duration to microseconds, or
50 /// timekeeper.after(std::chrono::duration_cast<Duration>(
54 virtual ~Timekeeper() = default;
56 /// Returns a future that will complete after the given duration with the
57 /// elapsed time. Exceptional errors can happen but they must be
58 /// exceptional. Use the steady (monotonic) clock.
60 /// You may cancel this Future to reclaim resources.
62 /// This future probably completes on the timer thread. You should almost
63 /// certainly follow it with a via() call or the accuracy of other timers
65 virtual Future<Unit> after(Duration) = 0;
67 /// Returns a future that will complete at the requested time.
69 /// You may cancel this Future to reclaim resources.
71 /// NB This is sugar for `after(when - now)`, so while you are welcome to
72 /// use a std::chrono::system_clock::time_point it will not track changes to
73 /// the system clock but rather execute that many milliseconds in the future
74 /// according to the steady clock.
75 template <class Clock>
76 Future<Unit> at(std::chrono::time_point<Clock> when);
81 // now get those definitions
82 #include <folly/futures/Future.h>
84 // finally we can use Future
87 template <class Clock>
88 Future<Unit> Timekeeper::at(std::chrono::time_point<Clock> when) {
89 auto now = Clock::now();
95 return after(std::chrono::duration_cast<Duration>(when - now));