Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
system_bootstrapper.h
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
53#pragma once
54
57#include "../patterns/result.h"
58
59#include <functional>
60#include <memory>
61#include <mutex>
62#include <string>
63#include <utility>
64#include <vector>
65
67
91public:
98 SystemBootstrapper() = default;
99
107
108 // Non-copyable
111
112 // Movable
113 SystemBootstrapper(SystemBootstrapper&& other) noexcept;
115
116 // =========================================================================
117 // Fluent Configuration API
118 // =========================================================================
119
133
148 SystemBootstrapper& with_logger(const std::string& name,
150
161 SystemBootstrapper& on_initialize(std::function<void()> callback);
162
173 SystemBootstrapper& on_shutdown(std::function<void()> callback);
174
175 // =========================================================================
176 // Security Configuration
177 // =========================================================================
178
203 SystemBootstrapper& with_auto_freeze(bool freeze_logger_registry = true,
204 bool freeze_service_container = true);
205
206 // =========================================================================
207 // Lifecycle Management
208 // =========================================================================
209
228
242 void shutdown();
243
249 bool is_initialized() const noexcept;
250
260 void reset();
261
262private:
269
274
279
283 void clear_loggers();
284
285 // Configuration state
286 interfaces::LoggerFactory default_logger_factory_;
287 std::vector<std::pair<std::string, interfaces::LoggerFactory>> named_logger_factories_;
288 std::vector<std::function<void()>> init_callbacks_;
289 std::vector<std::function<void()>> shutdown_callbacks_;
290
291 // Security configuration
294
295 // Lifecycle state
296 bool initialized_ = false;
297 mutable std::mutex state_mutex_;
298};
299
300// =============================================================================
301// SystemBootstrapper Implementation
302// =============================================================================
303
305 if (initialized_) {
306 shutdown();
307 }
308}
309
311 : default_logger_factory_(std::move(other.default_logger_factory_))
312 , named_logger_factories_(std::move(other.named_logger_factories_))
313 , init_callbacks_(std::move(other.init_callbacks_))
314 , shutdown_callbacks_(std::move(other.shutdown_callbacks_))
315 , auto_freeze_logger_registry_(other.auto_freeze_logger_registry_)
316 , auto_freeze_service_container_(other.auto_freeze_service_container_)
317 , initialized_(other.initialized_) {
318 other.initialized_ = false; // Prevent double shutdown
319}
320
322 SystemBootstrapper&& other) noexcept {
323 if (this != &other) {
324 // Shutdown current state if initialized
325 if (initialized_) {
326 shutdown();
327 }
328
329 default_logger_factory_ = std::move(other.default_logger_factory_);
330 named_logger_factories_ = std::move(other.named_logger_factories_);
331 init_callbacks_ = std::move(other.init_callbacks_);
332 shutdown_callbacks_ = std::move(other.shutdown_callbacks_);
333 auto_freeze_logger_registry_ = other.auto_freeze_logger_registry_;
334 auto_freeze_service_container_ = other.auto_freeze_service_container_;
335 initialized_ = other.initialized_;
336 other.initialized_ = false; // Prevent double shutdown
337 }
338 return *this;
339}
340
343 default_logger_factory_ = std::move(factory);
344 return *this;
345}
346
348 const std::string& name,
350 // Check if name already exists and update, otherwise add
351 for (auto& entry : named_logger_factories_) {
352 if (entry.first == name) {
353 entry.second = std::move(factory);
354 return *this;
355 }
356 }
357 named_logger_factories_.emplace_back(name, std::move(factory));
358 return *this;
359}
360
362 std::function<void()> callback) {
363 if (callback) {
364 init_callbacks_.push_back(std::move(callback));
365 }
366 return *this;
367}
368
370 std::function<void()> callback) {
371 if (callback) {
372 shutdown_callbacks_.push_back(std::move(callback));
373 }
374 return *this;
375}
376
378 bool freeze_logger_registry,
379 bool freeze_service_container) {
380 auto_freeze_logger_registry_ = freeze_logger_registry;
381 auto_freeze_service_container_ = freeze_service_container;
382 return *this;
383}
384
386 std::lock_guard<std::mutex> lock(state_mutex_);
387
388 if (initialized_) {
391 "SystemBootstrapper already initialized",
392 "bootstrap::SystemBootstrapper"
393 );
394 }
395
396 // Step 1: Register all loggers
397 auto result = register_loggers();
398 if (result.is_err()) {
399 return result;
400 }
401
402 // Step 2: Execute initialization callbacks
404
405 // Step 3: Freeze registries if auto-freeze is enabled
408 }
411 }
412
413 // Step 4: Mark as initialized
414 initialized_ = true;
415
416 return VoidResult::ok({});
417}
418
420 std::lock_guard<std::mutex> lock(state_mutex_);
421
422 if (!initialized_) {
423 return; // Already shutdown or never initialized
424 }
425
426 // Step 1: Execute shutdown callbacks in reverse order
428
429 // Step 2: Clear loggers from registry
431
432 // Step 3: Mark as not initialized
433 initialized_ = false;
434}
435
436inline bool SystemBootstrapper::is_initialized() const noexcept {
437 std::lock_guard<std::mutex> lock(state_mutex_);
438 return initialized_;
439}
440
442 // Shutdown if initialized
443 if (is_initialized()) {
444 shutdown();
445 }
446
447 std::lock_guard<std::mutex> lock(state_mutex_);
448
449 // Clear all configuration
450 default_logger_factory_ = nullptr;
452 init_callbacks_.clear();
453 shutdown_callbacks_.clear();
456}
457
460
461 // Register default logger
463 auto logger = default_logger_factory_();
464 if (!logger) {
467 "Default logger factory returned null",
468 "bootstrap::SystemBootstrapper"
469 );
470 }
471 auto result = registry.set_default_logger(std::move(logger));
472 if (result.is_err()) {
473 return result;
474 }
475 }
476
477 // Register named loggers
478 for (const auto& [name, factory] : named_logger_factories_) {
479 if (!factory) {
480 continue; // Skip null factories
481 }
482 auto logger = factory();
483 if (!logger) {
486 "Logger factory for '" + name + "' returned null",
487 "bootstrap::SystemBootstrapper"
488 );
489 }
490 auto result = registry.register_logger(name, std::move(logger));
491 if (result.is_err()) {
492 // Clean up already registered loggers
494 return result;
495 }
496 }
497
498 return VoidResult::ok({});
499}
500
502 for (const auto& callback : init_callbacks_) {
503 if (callback) {
504 callback();
505 }
506 }
507}
508
510 // Execute in reverse order (LIFO)
511 for (auto it = shutdown_callbacks_.rbegin();
512 it != shutdown_callbacks_.rend();
513 ++it) {
514 if (*it) {
515 (*it)();
516 }
517 }
518}
519
523
524} // namespace kcenon::common::bootstrap
Result type for error handling with member function support.
Definition core.cppm:165
static Result< T > ok(U &&value)
Create a successful result with value (static factory)
Definition core.h:223
Fluent API for system initialization and logger registration.
VoidResult register_loggers()
Register all loggers with GlobalLoggerRegistry.
std::vector< std::function< void()> > init_callbacks_
void clear_loggers()
Clear all loggers from GlobalLoggerRegistry.
void reset()
Reset the bootstrapper to initial state.
bool is_initialized() const noexcept
Check if the system is initialized.
SystemBootstrapper & with_auto_freeze(bool freeze_logger_registry=true, bool freeze_service_container=true)
Enable automatic freezing of registries after initialization.
SystemBootstrapper()=default
Default constructor.
void execute_init_callbacks()
Execute all initialization callbacks.
SystemBootstrapper & with_default_logger(interfaces::LoggerFactory factory)
Register a factory for the default logger.
~SystemBootstrapper()
Destructor with automatic shutdown.
std::vector< std::function< void()> > shutdown_callbacks_
SystemBootstrapper & with_logger(const std::string &name, interfaces::LoggerFactory factory)
Register a factory for a named logger.
std::vector< std::pair< std::string, interfaces::LoggerFactory > > named_logger_factories_
void execute_shutdown_callbacks()
Execute all shutdown callbacks in reverse order.
SystemBootstrapper & on_shutdown(std::function< void()> callback)
Register a shutdown callback.
VoidResult initialize()
Initialize the system.
SystemBootstrapper & operator=(const SystemBootstrapper &)=delete
SystemBootstrapper(const SystemBootstrapper &)=delete
SystemBootstrapper & on_initialize(std::function< void()> callback)
Register an initialization callback.
void freeze()
Freeze the container to prevent further registrations.
static service_container & global()
Get the global service container instance.
static GlobalLoggerRegistry & instance()
Get the singleton instance of GlobalLoggerRegistry.
void freeze()
Freeze the registry to prevent further modifications.
void clear()
Clear all registered loggers and factories.
GlobalLoggerRegistry implementation for runtime binding.
constexpr int ALREADY_EXISTS
Definition compat.h:37
constexpr int INTERNAL_ERROR
Definition compat.h:42
std::function< std::shared_ptr< ILogger >()> LoggerFactory
Factory function type for creating logger instances.
Result< T > make_error(int code, const std::string &message, const std::string &module="")
Create an error result with code and message.
Definition utilities.h:91
Umbrella header for Result<T> type and related utilities.
Implementation of the service container for dependency injection.