Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
database_coordinator.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
6
10
11#include <chrono>
12#include <stdexcept>
13
14namespace database
15{
16namespace integrated
17{
18
19// Helper to create error result
20namespace
21{
22 inline common::VoidResult make_error(const std::string& msg, int code = -1)
23 {
24 return common::VoidResult(common::error_info{ code, msg, "" });
25 }
26}
27
28// ═══════════════════════════════════════════════════════════════
29// PIMPL Implementation
30// ═══════════════════════════════════════════════════════════════
31
33{
34public:
35 explicit impl(const unified_db_config& config)
36 : config_(config)
37 , initialized_(false)
38 , logger_(nullptr)
39 , monitor_(nullptr)
40 , thread_pool_(nullptr)
41 , init_time_()
42 {
43 }
44
46 {
47 if (initialized_)
48 {
49 shutdown();
50 }
51 }
52
54 {
55 if (initialized_)
56 {
57 return make_error("Coordinator already initialized");
58 }
59
60 init_time_ = std::chrono::system_clock::now();
61
62 try
63 {
64 // ═══════════════════════════════════════════════════════════════
65 // Phase 1: Initialize Logger (for observability of other inits)
66 // ═══════════════════════════════════════════════════════════════
67 logger_ = std::make_unique<adapters::logger_adapter>(config_.logger);
68
69 auto logger_result = logger_->initialize();
70 if (!logger_result.is_ok())
71 {
72 logger_.reset();
73 return make_error(
74 "Logger initialization failed: "
75#if defined(USE_COMMON_SYSTEM)
76 + logger_result.error().message
77#else
78 + logger_result.error().message
79#endif
80 );
81 }
82
83 logger_->log(db_log_level::info, "Database coordinator: Logger initialized");
84
85 // ═══════════════════════════════════════════════════════════════
86 // Phase 2: Initialize Monitoring (for metrics collection)
87 // ═══════════════════════════════════════════════════════════════
88 monitor_ = std::make_unique<adapters::monitoring_adapter>(config_.monitoring);
89
90 auto monitor_result = monitor_->initialize();
91 if (!monitor_result.is_ok())
92 {
93 logger_->log(db_log_level::error, "Monitoring initialization failed");
94
95 // Rollback: shutdown logger
96 logger_->shutdown();
97 logger_.reset();
98 monitor_.reset();
99
100 return make_error(
101 "Monitoring initialization failed: "
102#if defined(USE_COMMON_SYSTEM)
103 + monitor_result.error().message
104#else
105 + monitor_result.error().message
106#endif
107 );
108 }
109
110 logger_->log(db_log_level::info, "Database coordinator: Monitoring initialized");
111
112 // ═══════════════════════════════════════════════════════════════
113 // Phase 3: Initialize Thread Pool (for async operations)
114 // ═══════════════════════════════════════════════════════════════
115 thread_pool_ = std::make_unique<adapters::thread_adapter>(config_.thread);
116
117 auto thread_result = thread_pool_->initialize();
118 if (!thread_result.is_ok())
119 {
120 logger_->log(db_log_level::error, "Thread pool initialization failed");
121
122 // Rollback: shutdown monitor and logger
123 monitor_->shutdown();
124 monitor_.reset();
125 logger_->shutdown();
126 logger_.reset();
127 thread_pool_.reset();
128
129 return make_error(
130 "Thread pool initialization failed: "
131#if defined(USE_COMMON_SYSTEM)
132 + thread_result.error().message
133#else
134 + thread_result.error().message
135#endif
136 );
137 }
138
139 logger_->log(db_log_level::info, "Database coordinator: Thread pool initialized");
140
141 // ═══════════════════════════════════════════════════════════════
142 // Initialization Complete
143 // ═══════════════════════════════════════════════════════════════
144 initialized_ = true;
145
147 "Database coordinator: All adapters initialized successfully");
148
149 return common::ok();
150 }
151 catch (const std::exception& e)
152 {
153 // Clean up any partially initialized adapters
154 if (thread_pool_)
155 {
156 thread_pool_->shutdown();
157 thread_pool_.reset();
158 }
159 if (monitor_)
160 {
161 monitor_->shutdown();
162 monitor_.reset();
163 }
164 if (logger_)
165 {
167 std::string("Exception during initialization: ") + e.what());
168 logger_->shutdown();
169 logger_.reset();
170 }
171
172 return make_error(std::string("Exception during initialization: ") + e.what());
173 }
174 }
175
177 {
178 if (!initialized_)
179 {
180 return common::ok(); // Already shut down
181 }
182
183 try
184 {
185 // Shutdown in REVERSE order of initialization
186 // This ensures dependencies are torn down safely
187
188 // ═══════════════════════════════════════════════════════════════
189 // Phase 1: Shutdown Thread Pool
190 // ═══════════════════════════════════════════════════════════════
191 if (thread_pool_)
192 {
193 if (logger_)
194 {
196 "Database coordinator: Shutting down thread pool");
197 }
198
199 auto thread_result = thread_pool_->shutdown();
200 if (!thread_result.is_ok())
201 {
202 if (logger_)
203 {
205 "Thread pool shutdown warning: "
206#if defined(USE_COMMON_SYSTEM)
207 + thread_result.error().message
208#else
209 + thread_result.error().message
210#endif
211 );
212 }
213 }
214
215 thread_pool_.reset();
216 }
217
218 // ═══════════════════════════════════════════════════════════════
219 // Phase 2: Shutdown Monitoring
220 // ═══════════════════════════════════════════════════════════════
221 if (monitor_)
222 {
223 if (logger_)
224 {
226 "Database coordinator: Shutting down monitoring");
227 }
228
229 auto monitor_result = monitor_->shutdown();
230 if (!monitor_result.is_ok())
231 {
232 if (logger_)
233 {
235 "Monitoring shutdown warning: "
236#if defined(USE_COMMON_SYSTEM)
237 + monitor_result.error().message
238#else
239 + monitor_result.error().message
240#endif
241 );
242 }
243 }
244
245 monitor_.reset();
246 }
247
248 // ═══════════════════════════════════════════════════════════════
249 // Phase 3: Shutdown Logger (LAST - keep logging until the end)
250 // ═══════════════════════════════════════════════════════════════
251 if (logger_)
252 {
254 "Database coordinator: Shutdown complete");
255 logger_->flush(); // Ensure all logs are written
256
257 auto logger_result = logger_->shutdown();
258 // Don't log logger shutdown errors (logger is shutting down!)
259
260 logger_.reset();
261 }
262
263 initialized_ = false;
264
265 return common::ok();
266 }
267 catch (const std::exception& e)
268 {
269 // Best effort cleanup
270 thread_pool_.reset();
271 monitor_.reset();
272 logger_.reset();
273
274 initialized_ = false;
275
276 return make_error(std::string("Exception during shutdown: ") + e.what());
277 }
278 }
279
280 bool is_initialized() const
281 {
282 return initialized_;
283 }
284
286 {
287 return logger_.get();
288 }
289
291 {
292 return monitor_.get();
293 }
294
296 {
297 return thread_pool_.get();
298 }
299
301 {
302 if (!initialized_)
303 {
305 common::error_info{ -1, "Coordinator not initialized", "" }
306 );
307 }
308
309 bool overall_healthy = true;
310
311 // Check logger
312 if (!logger_)
313 {
314 overall_healthy = false;
315 }
316
317 // Check monitoring
318 if (!monitor_)
319 {
320 overall_healthy = false;
321 }
322 else
323 {
324 auto monitor_health = monitor_->check_health();
325 if (!monitor_health.is_ok())
326 {
327 overall_healthy = false;
328 if (logger_)
329 {
330 logger_->log(db_log_level::warning, "Monitoring health check failed");
331 }
332 }
333 }
334
335 // Check thread pool
336 if (!thread_pool_)
337 {
338 overall_healthy = false;
339 }
340 // Thread pool is healthy if it exists
341 // (No statistics method available in thread_adapter yet)
342
343 return common::Result<bool>(overall_healthy);
344 }
345
347 {
348 coordinator_stats stats;
350 stats.logger_healthy = (logger_ != nullptr);
351 stats.monitoring_healthy = (monitor_ != nullptr);
352 stats.thread_pool_healthy = (thread_pool_ != nullptr);
353 stats.init_time = init_time_;
354
355 if (initialized_)
356 {
357 auto now = std::chrono::system_clock::now();
358 stats.uptime
359 = std::chrono::duration_cast<std::chrono::milliseconds>(now - init_time_);
360 }
361 else
362 {
363 stats.uptime = std::chrono::milliseconds(0);
364 }
365
367 }
368
369private:
372
373 // Adapters (in initialization order)
374 std::unique_ptr<adapters::logger_adapter> logger_;
375 std::unique_ptr<adapters::monitoring_adapter> monitor_;
376 std::unique_ptr<adapters::thread_adapter> thread_pool_;
377
378 // Statistics
379 std::chrono::system_clock::time_point init_time_;
380};
381
382// ═══════════════════════════════════════════════════════════════
383// Public Interface
384// ═══════════════════════════════════════════════════════════════
385
387 : pimpl_(std::make_unique<impl>(config))
388{
389}
390
392
394database_coordinator& database_coordinator::operator=(database_coordinator&&) noexcept = default;
395
397{
398 return pimpl_->initialize();
399}
400
402{
403 return pimpl_->shutdown();
404}
405
407{
408 return pimpl_->is_initialized();
409}
410
415
420
425
427{
428 return pimpl_->check_health();
429}
430
435
436} // namespace integrated
437} // namespace database
Unified logging adapter for database operations.
Monitoring adapter for database operations.
Thread pool adapter for async database operations.
common::Result< database_coordinator::coordinator_stats > get_stats() const
std::unique_ptr< adapters::thread_adapter > thread_pool_
std::unique_ptr< adapters::monitoring_adapter > monitor_
std::unique_ptr< adapters::logger_adapter > logger_
std::chrono::system_clock::time_point init_time_
Manages lifecycle and coordination of all database system adapters.
common::Result< bool > check_health()
Perform aggregate health check of all adapters.
database_coordinator(const unified_db_config &config)
Construct coordinator with configuration.
adapters::logger_adapter * get_logger()
Get logger adapter.
adapters::thread_adapter * get_thread_pool()
Get thread adapter.
common::Result< coordinator_stats > get_stats() const
common::VoidResult shutdown()
Shutdown all adapters in reverse order.
bool is_initialized() const
Check if coordinator is initialized.
common::VoidResult initialize()
Initialize all adapters in correct order.
adapters::monitoring_adapter * get_monitor()
Get monitoring adapter.
~database_coordinator()
Destructor - ensures graceful shutdown.
Lifecycle manager for all database system adapters (Phase 5)
Database logging adapter with runtime backend selection.
Database monitoring adapter with runtime backend selection.
VoidResult ok()
Result< std::monostate > VoidResult
@ info
Informational messages (default)
kcenon::common::VoidResult VoidResult
Primary VoidResult type - use this for void operations.
Definition result.h:33
db_logger_config logger
Logger configuration.
db_monitoring_config monitoring
Monitoring configuration.
db_thread_config thread
Thread pool configuration.
Thread pool adapter with runtime backend selection.