Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1359
61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <cassert>
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <mutex>
|
|
#include <random>
|
|
#include <thread>
|
|
|
|
namespace utils {
|
|
|
|
/**
|
|
* @brief - Keeps track of how long it's been since `Notify` method was called.
|
|
* If it wasn't called for a sufficiently long time interval (randomly chosen
|
|
* between `min_timeout` and `max_timeout`), the watchdog will periodically call
|
|
* `callback` until it is notified or destroyed. If `blocked` is set to true,
|
|
* watchdog will be blocked on startup.
|
|
*/
|
|
class Watchdog {
|
|
public:
|
|
Watchdog(const std::chrono::milliseconds &min_timeout,
|
|
const std::chrono::milliseconds &max_timeout,
|
|
const std::function<void()> &callback, bool blocked = false);
|
|
~Watchdog();
|
|
Watchdog(Watchdog &&) = delete;
|
|
Watchdog(const Watchdog &) = delete;
|
|
Watchdog &operator=(Watchdog &&) = delete;
|
|
Watchdog &operator=(const Watchdog &) = delete;
|
|
|
|
void Notify();
|
|
|
|
/** Calling `Block` is equivalent to continuously calling `Notify`
|
|
* until `Unblock` is called.
|
|
*/
|
|
void Block();
|
|
void Unblock();
|
|
|
|
private:
|
|
void Run();
|
|
|
|
std::chrono::milliseconds min_timeout_;
|
|
std::chrono::milliseconds max_timeout_;
|
|
|
|
std::mutex mutex_;
|
|
|
|
// Used to generate callback timeouts.
|
|
std::mt19937 generator_;
|
|
std::uniform_int_distribution<int> distribution_;
|
|
std::chrono::steady_clock::time_point callback_threshold_;
|
|
|
|
std::function<void()> callback_;
|
|
|
|
// Used to notify the watchdog loop it should stop.
|
|
std::atomic<bool> draining_;
|
|
std::atomic<bool> blocked_;
|
|
std::thread thread_;
|
|
};
|
|
|
|
} // namespace utils
|