Apache Mesos
timer.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License
12 
13 #ifndef __PROCESS_METRICS_TIMER_HPP__
14 #define __PROCESS_METRICS_TIMER_HPP__
15 
16 #include <atomic>
17 #include <memory>
18 #include <string>
19 
20 #include <process/clock.hpp>
21 #include <process/future.hpp>
22 
24 
25 #include <stout/duration.hpp>
26 #include <stout/hashmap.hpp>
27 #include <stout/option.hpp>
28 #include <stout/synchronized.hpp>
29 #include <stout/try.hpp>
30 
31 namespace process {
32 namespace metrics {
33 
34 // A Metric that represents a timed event. It is templated on a Duration
35 // subclass that specifies the unit to use for the Timer.
36 template <class T>
37 class Timer : public Metric
38 {
39 public:
40  // The Timer name will have a unit suffix added automatically.
41  Timer(const std::string& name, const Option<Duration>& window = None())
42  : Metric(name + "_" + T::units(), window),
43  data(new Data()) {}
44 
45  Future<double> value() const override
46  {
48 
49  synchronized (data->lock) {
50  if (data->lastValue.isSome()) {
51  value = data->lastValue.get();
52  } else {
53  value = Failure("No value");
54  }
55  }
56 
57  return value;
58  }
59 
60  // Start the Timer.
61  void start()
62  {
63  synchronized (data->lock) {
64  data->start = Clock::now();
65  }
66  }
67 
68  // Stop the Timer.
69  T stop()
70  {
71  const Time stop = Clock::now();
72 
73  T t(0);
74 
75  double value = 0.0;
76 
77  synchronized (data->lock) {
78  t = T(stop - data->start);
79 
80  data->lastValue = t.value();
81 
82  value = data->lastValue.get();
83  }
84 
85  push(value);
86 
87  return t;
88  }
89 
90  // Time an asynchronous event.
91  template <typename U>
92  Future<U> time(const Future<U>& future)
93  {
94  // We need to take a copy of 'this' here to ensure that the
95  // Timer is not destroyed in the interim.
96  future
97  .onAny(lambda::bind(_time, Clock::now(), *this));
98 
99  return future;
100  }
101 
102 private:
103  struct Data {
104  Data() = default;
105  std::atomic_flag lock = ATOMIC_FLAG_INIT;
106  Time start;
107  Option<double> lastValue;
108  };
109 
110  static void _time(Time start, Timer that)
111  {
112  const Time stop = Clock::now();
113 
114  double value;
115 
116  synchronized (that.data->lock) {
117  that.data->lastValue = T(stop - start).value();
118  value = that.data->lastValue.get();
119  }
120 
121  that.push(value);
122  }
123 
124  std::shared_ptr<Data> data;
125 };
126 
127 } // namespace metrics {
128 } // namespace process {
129 
130 #endif // __PROCESS_METRICS_TIMER_HPP__
Definition: timer.hpp:37
void start()
Definition: timer.hpp:61
Definition: future.hpp:668
Definition: metric.hpp:33
T stop()
Definition: timer.hpp:69
Future< U > time(const Future< U > &future)
Definition: timer.hpp:92
const Future< T > & onAny(AnyCallback &&callback) const
Definition: future.hpp:1445
Definition: time.hpp:23
Timer(const std::string &name, const Option< Duration > &window=None())
Definition: timer.hpp:41
Definition: none.hpp:27
const std::string & name() const
Definition: metric.hpp:39
Definition: executor.hpp:48
static Time now()
The current clock time for either the current process that makes this call or the global clock time i...
void push(double value)
Definition: metric.hpp:63
Try< Nothing > bind(int_fd s, const Address &address)
Definition: network.hpp:46
PID< MetricsProcess > metrics
Future< double > value() const override
Definition: timer.hpp:45
Definition: future.hpp:58