Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
CircuitBreaker.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <atomic>
10#include <chrono>
11#include <cstdint>
12
13namespace corium::safety {
14
16enum class CircuitState : uint8_t {
17 Closed,
18 Open,
20};
21
27template <
28 uint32_t FailureThreshold = 3,
29 uint32_t RecoveryTimeoutMs = 500
30>
32public:
33 CircuitBreaker() noexcept = default;
34
37 [[nodiscard]] bool allowExecution() noexcept
38 {
39 const CircuitState currentState = _state.load(std::memory_order_acquire);
40
41 if (currentState == CircuitState::Closed) {
42 return true;
43 }
44
45 if (currentState == CircuitState::Open) {
46 const uint64_t now = nowMs();
47 const uint64_t trippedAt = _trippedAtMs.load(std::memory_order_acquire);
48 if (now >= trippedAt && (now - trippedAt) >= RecoveryTimeoutMs) {
49 // Attempt transition to HalfOpen
51 if (_state.compare_exchange_strong(expected, CircuitState::HalfOpen, std::memory_order_acq_rel)) {
52 return true;
53 }
54 }
55 return false;
56 }
57
58 // HalfOpen: allow execution for probing
59 return true;
60 }
61
64 void recordSuccess() noexcept
65 {
66 _failureCount.store(0, std::memory_order_relaxed);
67 _state.store(CircuitState::Closed, std::memory_order_release);
68 }
69
72 void recordFailure() noexcept
73 {
74 const uint32_t count = _failureCount.fetch_add(1, std::memory_order_relaxed) + 1;
75 if (count >= FailureThreshold) {
76 _trippedAtMs.store(nowMs(), std::memory_order_release);
77 _state.store(CircuitState::Open, std::memory_order_release);
78 }
79 }
80
82 void reset() noexcept
83 {
84 _failureCount.store(0, std::memory_order_relaxed);
85 _trippedAtMs.store(0, std::memory_order_relaxed);
86 _state.store(CircuitState::Closed, std::memory_order_release);
87 }
88
90 void trip() noexcept
91 {
92 _trippedAtMs.store(nowMs(), std::memory_order_release);
93 _state.store(CircuitState::Open, std::memory_order_release);
94 }
95
97 [[nodiscard]] CircuitState state() const noexcept
98 {
99 const CircuitState s = _state.load(std::memory_order_acquire);
100 if (s == CircuitState::Open) {
101 const uint64_t now = nowMs();
102 const uint64_t tripped = _trippedAtMs.load(std::memory_order_acquire);
103 if (now >= tripped && (now - tripped) >= RecoveryTimeoutMs) {
105 }
106 }
107 return s;
108 }
109
111 [[nodiscard]] uint32_t failureCount() const noexcept
112 {
113 return _failureCount.load(std::memory_order_relaxed);
114 }
115
120 template <typename Callable>
121 bool execute(Callable&& fn)
122 {
123 if (!allowExecution()) {
124 return false;
125 }
126
127 bool ok = false;
128#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
129 try {
130 ok = fn();
131 } catch (...) {
132 ok = false;
133 }
134#else
135 ok = fn();
136#endif
137
138 if (ok) {
140 } else {
142 }
143
144 return ok;
145 }
146
147private:
148 [[nodiscard]] static uint64_t nowMs() noexcept
149 {
150 return static_cast<uint64_t>(
151 std::chrono::duration_cast<std::chrono::milliseconds>(
152 std::chrono::steady_clock::now().time_since_epoch()
153 ).count()
154 );
155 }
156
157 std::atomic<CircuitState> _state{CircuitState::Closed};
158 std::atomic<uint32_t> _failureCount{0};
159 std::atomic<uint64_t> _trippedAtMs{0};
160};
161
162} // namespace corium::safety
Zero-allocation Circuit Breaker pattern for isolating faulty handlers or peripheral links....
Definition CircuitBreaker.hpp:31
void recordFailure() noexcept
Record a failed operation. Increments failure counter and trips circuit Open if threshold is reached.
Definition CircuitBreaker.hpp:72
bool allowExecution() noexcept
Check if execution is permitted under current circuit state. Automatically transitions from Open to H...
Definition CircuitBreaker.hpp:37
void trip() noexcept
Manually trip the circuit breaker open.
Definition CircuitBreaker.hpp:90
void recordSuccess() noexcept
Record a successful operation execution. Resets consecutive failure counter and restores Closed state...
Definition CircuitBreaker.hpp:64
uint32_t failureCount() const noexcept
Current consecutive failure count.
Definition CircuitBreaker.hpp:111
CircuitState state() const noexcept
Current state of the circuit breaker.
Definition CircuitBreaker.hpp:97
CircuitBreaker() noexcept=default
bool execute(Callable &&fn)
Execute a protected callable through the circuit breaker.
Definition CircuitBreaker.hpp:121
void reset() noexcept
Manually reset the circuit breaker to normal Closed state.
Definition CircuitBreaker.hpp:82
Definition CircuitBreaker.hpp:13
CircuitState
Circuit Breaker operational state.
Definition CircuitBreaker.hpp:16
@ Closed
Normal operation: all calls execute.
@ Open
Tripped/Faulty: calls are fast-failed without execution.
@ HalfOpen
Recovery probing: allowing a single canary call to verify health.