Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::utils::health_monitor Class Reference

Monitors connection health with heartbeat mechanism. More...

#include <health_monitor.h>

Inheritance diagram for kcenon::network::utils::health_monitor:
Inheritance graph
Collaboration diagram for kcenon::network::utils::health_monitor:
Collaboration graph

Public Member Functions

 health_monitor (std::chrono::seconds heartbeat_interval=std::chrono::seconds(30), size_t max_missed_heartbeats=3)
 Constructs a health monitor.
 
 ~health_monitor () noexcept
 Destructor - stops monitoring if active.
 
auto start_monitoring (std::shared_ptr< core::messaging_client > client) -> void
 Starts monitoring the given client.
 
auto stop_monitoring () -> void
 Stops monitoring.
 
auto get_health () const -> connection_health
 Gets current health status.
 
auto set_health_callback (std::function< void(const connection_health &)> callback) -> void
 Sets callback for health status changes.
 
auto is_monitoring () const noexcept -> bool
 Checks if monitoring is active.
 

Private Member Functions

auto do_heartbeat () -> void
 Performs a single heartbeat check.
 
auto schedule_next_heartbeat () -> void
 Schedules the next heartbeat.
 
auto update_health (bool success, std::chrono::milliseconds response_time) -> void
 Updates health metrics.
 

Private Attributes

std::shared_ptr< core::messaging_clientclient_
 
std::unique_ptr< asio::io_context > io_context_
 
std::unique_ptr< asio::executor_work_guard< asio::io_context::executor_type > > work_guard_
 
std::unique_ptr< asio::steady_timer > heartbeat_timer_
 
std::future< void > io_future_
 
std::chrono::seconds heartbeat_interval_
 
size_t max_missed_heartbeats_
 
std::mutex health_mutex_
 
connection_health health_
 
std::atomic< bool > is_monitoring_ {false}
 
std::atomic< size_t > total_heartbeats_ {0}
 
std::atomic< size_t > failed_heartbeats_ {0}
 
std::function< void(const connection_health &)> health_callback_
 

Detailed Description

Monitors connection health with heartbeat mechanism.

Thread Safety

  • All public methods are thread-safe
  • Health metrics are protected by mutex
  • Heartbeat thread runs independently

Key Features

  • Periodic heartbeat messages
  • Automatic dead connection detection
  • Connection quality metrics (latency, packet loss)
  • Health status callbacks
  • Configurable heartbeat interval

Usage Example

auto client = std::make_shared<messaging_client>("client_id");
client->start_client("localhost", 8080);
auto monitor = std::make_shared<health_monitor>(
std::chrono::seconds(30) // heartbeat every 30 seconds
);
monitor->set_health_callback([](const connection_health& health) {
if (!health.is_alive) {
std::cerr << "Connection is dead!\n";
}
});
monitor->start_monitoring(client);
// ... later ...
auto health = monitor->get_health();
std::cout << "Missed heartbeats: " << health.missed_heartbeats << "\n";
monitor->stop_monitoring();
Contains connection health metrics.

Definition at line 74 of file health_monitor.h.

Constructor & Destructor Documentation

◆ health_monitor()

kcenon::network::utils::health_monitor::health_monitor ( std::chrono::seconds heartbeat_interval = std::chrono::seconds(30),
size_t max_missed_heartbeats = 3 )
explicit

Constructs a health monitor.

Parameters
heartbeat_intervalInterval between heartbeat checks (default: 30s)
max_missed_heartbeatsMaximum missed heartbeats before marking as dead (default: 3)

Definition at line 16 of file health_monitor.cpp.

18 : heartbeat_interval_(heartbeat_interval)
19 , max_missed_heartbeats_(max_missed_heartbeats)
20 {
21 health_.last_heartbeat = std::chrono::steady_clock::now();
22 NETWORK_LOG_INFO("[health_monitor] Created with interval=" +
23 std::to_string(heartbeat_interval.count()) + "s, max_missed=" +
24 std::to_string(max_missed_heartbeats));
25 }
#define NETWORK_LOG_INFO(msg)
std::chrono::steady_clock::time_point last_heartbeat

References health_, kcenon::network::utils::connection_health::last_heartbeat, and NETWORK_LOG_INFO.

◆ ~health_monitor()

kcenon::network::utils::health_monitor::~health_monitor ( )
noexcept

Destructor - stops monitoring if active.

Definition at line 27 of file health_monitor.cpp.

28 {
29 try
30 {
32 }
33 catch (...)
34 {
35 // Destructor must not throw
36 }
37 }
auto stop_monitoring() -> void
Stops monitoring.

References stop_monitoring().

Here is the call graph for this function:

Member Function Documentation

◆ do_heartbeat()

auto kcenon::network::utils::health_monitor::do_heartbeat ( ) -> void
private

Performs a single heartbeat check.

Sends a heartbeat message and waits for response. Updates health metrics based on the result.

Definition at line 156 of file health_monitor.cpp.

157 {
158 if (!is_monitoring_.load() || !client_)
159 {
160 return;
161 }
162
163 auto start_time = std::chrono::steady_clock::now();
164
165 // Check if client is still connected
166 bool is_connected = client_->is_connected();
167
168 total_heartbeats_.fetch_add(1);
169
170 if (is_connected)
171 {
172 // Send heartbeat packet (simple ping message)
173 std::vector<uint8_t> heartbeat_data = {
174 0xFF, 0xFE, // Magic bytes for heartbeat
175 0x01, // Heartbeat type
176 0x00 // Padding
177 };
178
179 auto send_result = client_->send_packet(std::move(heartbeat_data));
180
181 auto end_time = std::chrono::steady_clock::now();
182 auto response_time = std::chrono::duration_cast<std::chrono::milliseconds>(
183 end_time - start_time);
184
185 if (!send_result.is_err())
186 {
187 // Heartbeat successful
188 update_health(true, response_time);
189 NETWORK_LOG_DEBUG("[health_monitor] Heartbeat successful, response_time=" +
190 std::to_string(response_time.count()) + "ms");
191 }
192 else
193 {
194 // Heartbeat failed
195 failed_heartbeats_.fetch_add(1);
196 update_health(false, response_time);
197 NETWORK_LOG_WARN("[health_monitor] Heartbeat failed: " +
198 send_result.error().message);
199 }
200 }
201 else
202 {
203 // Client disconnected
204 failed_heartbeats_.fetch_add(1);
205 update_health(false, std::chrono::milliseconds(0));
206 NETWORK_LOG_WARN("[health_monitor] Client is disconnected");
207 }
208
209 // Schedule next heartbeat if still monitoring
210 if (is_monitoring_.load())
211 {
213 }
214 }
auto schedule_next_heartbeat() -> void
Schedules the next heartbeat.
std::shared_ptr< core::messaging_client > client_
auto update_health(bool success, std::chrono::milliseconds response_time) -> void
Updates health metrics.
#define NETWORK_LOG_WARN(msg)
#define NETWORK_LOG_DEBUG(msg)

References NETWORK_LOG_DEBUG, and NETWORK_LOG_WARN.

◆ get_health()

auto kcenon::network::utils::health_monitor::get_health ( ) const -> connection_health
nodiscard

Gets current health status.

Returns
Current connection health metrics

Definition at line 139 of file health_monitor.cpp.

140 {
141 std::lock_guard<std::mutex> lock(health_mutex_);
142 return health_;
143 }

References health_, and health_mutex_.

◆ is_monitoring()

auto kcenon::network::utils::health_monitor::is_monitoring ( ) const -> bool
nodiscardnoexcept

Checks if monitoring is active.

Returns
true if monitoring, false otherwise

Definition at line 151 of file health_monitor.cpp.

152 {
153 return is_monitoring_.load();
154 }

References is_monitoring_.

◆ schedule_next_heartbeat()

auto kcenon::network::utils::health_monitor::schedule_next_heartbeat ( ) -> void
private

Schedules the next heartbeat.

Definition at line 216 of file health_monitor.cpp.

217 {
218 if (!heartbeat_timer_ || !is_monitoring_.load())
219 {
220 return;
221 }
222
224
225 auto self = shared_from_this();
226 heartbeat_timer_->async_wait(
227 [this, self](const std::error_code& ec)
228 {
229 if (!ec && is_monitoring_.load())
230 {
231 do_heartbeat();
232 }
233 }
234 );
235 }
std::unique_ptr< asio::steady_timer > heartbeat_timer_
auto do_heartbeat() -> void
Performs a single heartbeat check.

◆ set_health_callback()

auto kcenon::network::utils::health_monitor::set_health_callback ( std::function< void(const connection_health &)> callback) -> void

Sets callback for health status changes.

Parameters
callbackFunction called when health status changes

The callback receives the current health metrics.

Definition at line 145 of file health_monitor.cpp.

147 {
148 health_callback_ = std::move(callback);
149 }
std::function< void(const connection_health &)> health_callback_

◆ start_monitoring()

auto kcenon::network::utils::health_monitor::start_monitoring ( std::shared_ptr< core::messaging_client > client) -> void

Starts monitoring the given client.

Parameters
clientClient to monitor

Begins periodic heartbeat checks. If client doesn't respond within the timeout, increments missed_heartbeats counter.

Definition at line 39 of file health_monitor.cpp.

41 {
42 if (is_monitoring_.load())
43 {
44 NETWORK_LOG_WARN("[health_monitor] Already monitoring");
45 return;
46 }
47
48 if (!client)
49 {
50 NETWORK_LOG_ERROR("[health_monitor] Cannot monitor null client");
51 return;
52 }
53
55
56 // Create io_context and work guard
57 io_context_ = std::make_unique<asio::io_context>();
58 work_guard_ = std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(
59 asio::make_work_guard(*io_context_)
60 );
61
62 // Create heartbeat timer
63 heartbeat_timer_ = std::make_unique<asio::steady_timer>(*io_context_);
64
65 is_monitoring_.store(true);
66
67 // Reset metrics
68 total_heartbeats_.store(0);
69 failed_heartbeats_.store(0);
70 {
71 std::lock_guard<std::mutex> lock(health_mutex_);
72 health_.is_alive = true;
75 health_.last_heartbeat = std::chrono::steady_clock::now();
76 }
77
78 // Submit io_context::run() to thread pool
80 [this]()
81 {
82 try
83 {
84 io_context_->run();
85 }
86 catch (const std::exception& e)
87 {
88 NETWORK_LOG_ERROR("[health_monitor] Exception in io_context run: " +
89 std::string(e.what()));
90 }
91 }
92 );
93
94 // Schedule first heartbeat
96
97 NETWORK_LOG_INFO("[health_monitor] Started monitoring");
98 }
static thread_integration_manager & instance()
Get the singleton instance.
std::future< void > submit_task(std::function< void()> task)
Submit a task to the thread pool.
std::unique_ptr< asio::executor_work_guard< asio::io_context::executor_type > > work_guard_
std::unique_ptr< asio::io_context > io_context_
#define NETWORK_LOG_ERROR(msg)

References kcenon::network::integration::thread_integration_manager::instance(), NETWORK_LOG_ERROR, NETWORK_LOG_INFO, NETWORK_LOG_WARN, and kcenon::network::integration::thread_integration_manager::submit_task().

Here is the call graph for this function:

◆ stop_monitoring()

auto kcenon::network::utils::health_monitor::stop_monitoring ( ) -> void

Stops monitoring.

Cancels the heartbeat timer and stops the monitoring thread.

Definition at line 100 of file health_monitor.cpp.

101 {
102 if (!is_monitoring_.exchange(false))
103 {
104 return;
105 }
106
107 // Cancel timer
109 {
110 heartbeat_timer_->cancel();
111 }
112
113 // Release work guard
114 if (work_guard_)
115 {
116 work_guard_.reset();
117 }
118
119 // Stop io_context
120 if (io_context_)
121 {
122 io_context_->stop();
123 }
124
125 // Wait for io_context task to complete
126 if (io_future_.valid())
127 {
128 io_future_.wait();
129 }
130
131 // Release resources
132 heartbeat_timer_.reset();
133 io_context_.reset();
134 client_.reset();
135
136 NETWORK_LOG_INFO("[health_monitor] Stopped monitoring");
137 }

References NETWORK_LOG_INFO.

Referenced by ~health_monitor().

Here is the caller graph for this function:

◆ update_health()

auto kcenon::network::utils::health_monitor::update_health ( bool success,
std::chrono::milliseconds response_time ) -> void
private

Updates health metrics.

Parameters
successWhether heartbeat was successful
response_timeResponse time in milliseconds

Definition at line 237 of file health_monitor.cpp.

239 {
240 std::lock_guard<std::mutex> lock(health_mutex_);
241
242 health_.last_heartbeat = std::chrono::steady_clock::now();
243 health_.last_response_time = response_time;
244
245 if (success)
246 {
247 // Reset missed heartbeats on success
249 health_.is_alive = true;
250 }
251 else
252 {
253 // Increment missed heartbeats
255
256 // Mark as dead if exceeded threshold
258 {
259 health_.is_alive = false;
260 NETWORK_LOG_ERROR("[health_monitor] Connection marked as DEAD (missed " +
261 std::to_string(health_.missed_heartbeats) + " heartbeats)");
262 }
263 }
264
265 // Calculate packet loss rate
266 auto total = total_heartbeats_.load();
267 auto failed = failed_heartbeats_.load();
268 if (total > 0)
269 {
270 health_.packet_loss_rate = static_cast<double>(failed) / static_cast<double>(total);
271 }
272
273 // Report metrics to monitoring system (optional)
274 try
275 {
277 auto monitor = monitor_mgr.get_monitoring();
278 if (monitor && client_)
279 {
280 // Use client pointer address as connection identifier
281 std::ostringstream oss;
282 oss << "client_" << static_cast<const void*>(client_.get());
283
284 monitor->report_health(
285 oss.str(),
287 static_cast<double>(health_.last_response_time.count()),
290 );
291 }
292 }
293 catch (...)
294 {
295 // Monitoring failure is not critical, continue normal operation
296 }
297
298 // Invoke health callback if set
300 {
302 }
303 }
static monitoring_integration_manager & instance()
Get the singleton instance.
std::chrono::milliseconds last_response_time

References kcenon::network::integration::monitoring_integration_manager::instance(), and NETWORK_LOG_ERROR.

Here is the call graph for this function:

Member Data Documentation

◆ client_

std::shared_ptr<core::messaging_client> kcenon::network::utils::health_monitor::client_
private

Monitored client

Definition at line 150 of file health_monitor.h.

◆ failed_heartbeats_

std::atomic<size_t> kcenon::network::utils::health_monitor::failed_heartbeats_ {0}
private

Failed heartbeats

Definition at line 166 of file health_monitor.h.

166{0};

◆ health_

connection_health kcenon::network::utils::health_monitor::health_
private

Current health metrics

Definition at line 162 of file health_monitor.h.

Referenced by get_health(), and health_monitor().

◆ health_callback_

std::function<void(const connection_health&)> kcenon::network::utils::health_monitor::health_callback_
private

Health callback

Definition at line 168 of file health_monitor.h.

◆ health_mutex_

std::mutex kcenon::network::utils::health_monitor::health_mutex_
mutableprivate

Protects health metrics

Definition at line 161 of file health_monitor.h.

Referenced by get_health().

◆ heartbeat_interval_

std::chrono::seconds kcenon::network::utils::health_monitor::heartbeat_interval_
private

Heartbeat interval

Definition at line 158 of file health_monitor.h.

◆ heartbeat_timer_

std::unique_ptr<asio::steady_timer> kcenon::network::utils::health_monitor::heartbeat_timer_
private

Heartbeat timer

Definition at line 155 of file health_monitor.h.

◆ io_context_

std::unique_ptr<asio::io_context> kcenon::network::utils::health_monitor::io_context_
private

IO context for timer

Definition at line 152 of file health_monitor.h.

◆ io_future_

std::future<void> kcenon::network::utils::health_monitor::io_future_
private

Future for io_context execution

Definition at line 156 of file health_monitor.h.

◆ is_monitoring_

std::atomic<bool> kcenon::network::utils::health_monitor::is_monitoring_ {false}
private

Monitoring active flag

Definition at line 164 of file health_monitor.h.

164{false};

Referenced by is_monitoring().

◆ max_missed_heartbeats_

size_t kcenon::network::utils::health_monitor::max_missed_heartbeats_
private

Max missed heartbeats before dead

Definition at line 159 of file health_monitor.h.

◆ total_heartbeats_

std::atomic<size_t> kcenon::network::utils::health_monitor::total_heartbeats_ {0}
private

Total heartbeats sent

Definition at line 165 of file health_monitor.h.

165{0};

◆ work_guard_

std::unique_ptr<asio::executor_work_guard<asio::io_context::executor_type> > kcenon::network::utils::health_monitor::work_guard_
private

Work guard to keep io_context running

Definition at line 154 of file health_monitor.h.


The documentation for this class was generated from the following files: