CommRaT 2.0.0
C++20 Real-Time Messaging Framework
Loading...
Searching...
No Matches
module_main.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <commrat/commrat.hpp>
6#include <rfl.hpp>
7#include <rfl/json.hpp>
8#include <csignal>
9#include <cstdlib>
10#include <iostream>
11#include <atomic>
12#include <string>
13
14namespace commrat {
15
16// Global flag for signal handling
17inline std::atomic<bool> g_shutdown_requested{false};
18
24inline void signal_handler(int signal) {
25 g_shutdown_requested.store(true);
26 std::cout << "\nReceived signal " << signal << ", shutting down...\n";
27}
28
60template<typename ModuleType, typename Registry>
61int module_main(const ModuleConfig& config) {
62 try {
63 // Install signal handlers
64 std::signal(SIGINT, signal_handler);
65 std::signal(SIGTERM, signal_handler);
66
67 // Create module instance
68 std::cout << "Starting " << config.name << " (system_id="
69 << static_cast<int>(config.system_id()) << ", instance_id="
70 << static_cast<int>(config.instance_id()) << ")\n";
71
72 ModuleType module(config);
73
74 // Start module (begins subscription protocol, starts threads)
75 module.start();
76 std::cout << config.name << " running (press Ctrl+C to stop)...\n";
77
78 // Wait for shutdown signal (0% CPU - blocking sleep)
79 while (!g_shutdown_requested.load()) {
81 }
82
83 // Stop module (graceful shutdown of threads, unsubscribe)
84 std::cout << "Stopping " << config.name << "...\n";
85 module.stop();
86
87 std::cout << config.name << " stopped successfully\n";
88 return g_shutdown_requested.load() ? 130 : 0; // 130 = SIGINT convention
89
90 } catch (const std::exception& e) {
91 std::cerr << "ERROR: " << e.what() << "\n";
92 return 1;
93 } catch (...) {
94 std::cerr << "ERROR: Unknown exception\n";
95 return 1;
96 }
97}
98
113template<typename ModuleType, typename Registry>
114int module_main(int argc, char** argv) {
115 try {
116 ModuleConfig config;
117
118 if (argc != 2) {
119 std::cerr << "ERROR: Configuration file required\n";
120 std::cerr << "Usage: " << argv[0] << " <config.json>\n";
121 return 1;
122 }
123
124 std::string filename = argv[1];
125 if (!filename.ends_with(".json")) {
126 std::cerr << "ERROR: Only JSON config files supported (got: " << filename << ")\n";
127 std::cerr << "Usage: " << argv[0] << " <config.json>\n";
128 return 1;
129 }
130
131 config = rfl::json::load<ModuleConfig>(filename).value();
132
133 // Call the main template function
134 return module_main<ModuleType, Registry>(config);
135
136 } catch (const std::exception& e) {
137 std::cerr << "Fatal error: " << e.what() << "\n";
138 return 1;
139 }
140}
141
142} // namespace commrat
143
166#define COMMRAT_MODULE_MAIN(ModuleType, Registry) \
167 int main(int argc, char** argv) { \
168 return commrat::module_main<ModuleType, Registry>(argc, argv); \
169 }
static void sleep(std::chrono::duration< Rep, Period > duration) noexcept
Sleep for specified duration.
Main CommRaT header - include this to get everything you need.
CommRaT - Modern C++ Real-Time Communication Framework.
std::atomic< bool > g_shutdown_requested
void signal_handler(int signal)
Signal handler for graceful shutdown.
std::chrono::milliseconds Milliseconds
Definition timestamp.hpp:39
int module_main(const ModuleConfig &config)
Main entry point for standalone module binaries.
uint8_t system_id() const
Get system_id - NoOutput or SimpleOutput only.
uint8_t instance_id() const
Get instance_id - NoOutput or SimpleOutput only.
Unified threading and synchronization abstractions for CommRaT.