1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef MS_BACKOFF_TIMER_HANDLE_INTERFACE_HPP
#define MS_BACKOFF_TIMER_HANDLE_INTERFACE_HPP
#include "common.hpp"
#include <limits> // std::numeric_limits()
#include <string>
class BackoffTimerHandleInterface
{
public:
class Listener
{
public:
virtual ~Listener() = default;
public:
/**
* Invoked on timeout expiration. The parent can modify the base
* timeout given as reference and affect the next timeout duration.
*
* @remarks
* - If the caller deletes this BackoffTimer instance within the callback
* it must signal it be setting `stop` to true.
*/
virtual void OnBackoffTimer(
BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop) = 0;
};
public:
enum class BackoffAlgorithm : uint8_t
{
// The base duration will be used for any restart.
FIXED,
// An exponential backoff is used for restarts, with a 2x multiplier,
// meaning that every restart will use a duration that is twice as long as
// the previous.
EXPONENTIAL,
};
public:
struct BackoffTimerHandleOptions
{
/**
* Listener on which `OnBackoffTimer()` callback will be invoked.
*/
BackoffTimerHandleInterface::Listener* listener{ nullptr };
/**
* Label.
*/
std::string label;
/**
* Base timeout duration (ms).
*/
uint64_t baseTimeoutMs;
/**
* Backoff algorithm.
*/
BackoffAlgorithm backoffAlgorithm;
/**
* Maximum duration of the backoff timeout (ms). If no value is given, no
* limit is set.
*/
std::optional<uint64_t> maxBackoffTimeoutMs;
/**
* Maximum number of restarts. If no value is given, it will restart
* forever until stopped.
*/
std::optional<size_t> maxRestarts;
};
public:
static constexpr uint64_t MaxTimeoutMs{ std::numeric_limits<uint64_t>::max() / 2 };
public:
BackoffTimerHandleInterface() = default;
BackoffTimerHandleInterface& operator=(const BackoffTimerHandleInterface&) = delete;
BackoffTimerHandleInterface(const BackoffTimerHandleInterface&) = delete;
virtual ~BackoffTimerHandleInterface() = default;
public:
/**
* Start the BackoffTimer (if it's stopped) or restart it (if already
* running). It will reset the timeout count.
*/
virtual void Start() = 0;
/**
* Stop the BackoffTimer. It will reset the timeout count.
*/
virtual void Stop() = 0;
/**
* Set the base timeout duration. It will be applied after the next timeout
* and effective duration can be larger if backoff algorithm is exponential.
*/
virtual void SetBaseTimeoutMs(uint64_t baseTimeoutMs) = 0;
/**
* Whether the BackoffTimer is running. Useful to check if this BackoffTimer
* will timeout again within the OnTimer() callback.
*/
virtual bool IsRunning() const = 0;
virtual const std::string GetLabel() const = 0;
/**
* Maximum number of restarts.
*
* @remarks
* - If `maxRestarts` was not given in the constructor, this method returns 0.
*/
virtual std::optional<size_t> GetMaxRestarts() const = 0;
/**
* Number of times the timer has expired.
*/
virtual size_t GetExpirationCount() const = 0;
};
#endif