15 #ifndef STATUS_MONITOR__STATUS_MONITOR_HPP_
16 #define STATUS_MONITOR__STATUS_MONITOR_HPP_
24 #include <unordered_map>
35 std::chrono::high_resolution_clock::time_point last_access;
38 decltype(std::chrono::high_resolution_clock::now() - std::chrono::high_resolution_clock::now());
40 duration minimum_access_interval;
42 duration maximum_access_interval;
46 template <
typename Name>
47 explicit Status(Name && name)
48 : name(std::forward<decltype(name)>(name)),
49 last_access(std::chrono::high_resolution_clock::now()),
50 minimum_access_interval(duration::max()),
51 maximum_access_interval(duration::min())
55 auto since_last_access()
const
57 return std::chrono::high_resolution_clock::now() - last_access;
60 auto good()
const {
return exited or since_last_access() < threshold; }
62 explicit operator bool()
const {
return good(); }
65 static inline std::ofstream file;
67 static inline std::unordered_map<std::thread::id, Status> statuses;
69 static inline std::thread watchdog;
71 static inline std::atomic_bool terminating;
73 static inline std::chrono::seconds threshold = std::chrono::seconds(10);
75 static inline std::mutex mutex;
82 template <
typename Name>
85 auto lock = std::scoped_lock<std::mutex>(mutex);
87 if (
auto iter = statuses.find(std::this_thread::get_id()); iter != std::end(statuses)) {
88 [[maybe_unused]]
auto && [id, status] = *iter;
90 const auto now = std::chrono::high_resolution_clock::now();
92 const auto this_access_interval = now - status.last_access;
94 status.minimum_access_interval =
95 std::min<std::decay_t<decltype(status.minimum_access_interval)>>(
96 status.minimum_access_interval, this_access_interval);
98 status.maximum_access_interval =
99 std::max<std::decay_t<decltype(status.maximum_access_interval)>>(
100 status.maximum_access_interval, this_access_interval);
102 status.last_access = now;
104 statuses.emplace(std::this_thread::get_id(), std::forward<decltype(name)>(name));
108 template <
typename T>
111 std::reference_wrapper<T> target;
116 template <
typename... Ts>
119 auto lock = std::scoped_lock<std::mutex>(mutex);
120 return std::exchange(std::forward<decltype(
xs)>(
xs)...);
123 template <
typename U>
132 template <
typename Thunk>
140 auto write() const ->
void;
Definition: status_monitor.hpp:110
ScopedExchanger(T &x, U &&y)
Definition: status_monitor.hpp:124
static auto locked_exchange(Ts &&... xs) -> decltype(auto)
Definition: status_monitor.hpp:117
~ScopedExchanger()
Definition: status_monitor.hpp:129
Definition: status_monitor.hpp:30
auto write() const -> void
Definition: status_monitor.cpp:80
~StatusMonitor()
Definition: status_monitor.cpp:59
auto overrideThreshold(const std::chrono::seconds &t, Thunk thunk) -> decltype(auto)
Definition: status_monitor.hpp:133
auto touch(Name &&name)
Definition: status_monitor.hpp:83
StatusMonitor()
Definition: status_monitor.cpp:38
Definition: concatenate.hpp:24
class common::StatusMonitor status_monitor
Definition: junit5.hpp:25
std::string string
Definition: junit5.hpp:26
TrafficLight::Status Status
Definition: test_traffic_light.cpp:25