#include "character_creation_worker.h" #include "produce_worker.h" #include "stockagemanager.h" #include "director_worker.h" #include "valuerecalculationworker.h" #include "connection_pool.h" #include "websocket_server.h" #include "message_broker.h" #include "usercharacterworker.h" #include "houseworker.h" #include "politics_worker.h" #include "underground_worker.h" #include "config.h" #include #include #include #include #include #include #include #include std::atomic keepRunning(true); std::atomic shutdownRequested(false); void handleSignal(int signal) { std::cerr << "Signal erhalten: " << signal << ". Beende Anwendung..." << std::endl; if (signal == SIGINT || signal == SIGTERM) { std::cerr << "Setze Shutdown-Flags..." << std::endl; keepRunning.store(false, std::memory_order_relaxed); shutdownRequested.store(true, std::memory_order_relaxed); std::cerr << "Shutdown-Flags gesetzt. keepRunning=" << keepRunning.load() << ", shutdownRequested=" << shutdownRequested.load() << std::endl; } } int main() { std::signal(SIGINT, handleSignal); std::signal(SIGTERM, handleSignal); try { Config config("/etc/yourpart/daemon.conf"); ConnectionPool pool( config.get("DB_HOST"), config.get("DB_PORT"), config.get("DB_NAME"), config.get("DB_USER"), config.get("DB_PASSWORD"), 10 ); int websocketPort = std::stoi(config.get("WEBSOCKET_PORT")); bool sslEnabled = config.get("WEBSOCKET_SSL_ENABLED") == "true"; std::string certPath = sslEnabled ? config.get("WEBSOCKET_SSL_CERT_PATH") : ""; std::string keyPath = sslEnabled ? config.get("WEBSOCKET_SSL_KEY_PATH") : ""; MessageBroker broker; WebSocketServer websocketServer(websocketPort, pool, broker, sslEnabled, certPath, keyPath); // Use C++23 features for better performance std::vector> workers; workers.reserve(9); // Pre-allocate for better performance workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); workers.emplace_back(std::make_unique(pool, broker)); websocketServer.setWorkers(workers); broker.start(); websocketServer.run(); for (auto &worker : workers) { worker->startWorkerThread(); worker->enableWatchdog(); } // Benachrichtige systemd, dass der Service bereit ist sd_notify(0, "READY=1"); // Hauptschleife mit besserer Signal-Behandlung std::cerr << "Hauptschleife gestartet. keepRunning=" << keepRunning.load() << ", shutdownRequested=" << shutdownRequested.load() << std::endl; while (keepRunning.load() && !shutdownRequested.load()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } std::cerr << "Hauptschleife beendet. keepRunning=" << keepRunning.load() << ", shutdownRequested=" << shutdownRequested.load() << std::endl; std::cerr << "Starte sauberes Herunterfahren..." << std::endl; auto shutdownStart = std::chrono::steady_clock::now(); const auto maxShutdownTime = std::chrono::seconds(10); // Stoppe alle Worker-Threads std::cerr << "Stoppe Worker-Threads..." << std::endl; for (auto &worker : workers) { worker->stopWorkerThread(); if (std::chrono::steady_clock::now() - shutdownStart > maxShutdownTime) { std::cerr << "Shutdown-Timeout erreicht, erzwinge Beendigung..." << std::endl; break; } } // Stoppe Watchdog-Threads std::cerr << "Stoppe Watchdog-Threads..." << std::endl; for (auto &worker : workers) { worker->stopWatchdogThread(); if (std::chrono::steady_clock::now() - shutdownStart > maxShutdownTime) { std::cerr << "Shutdown-Timeout erreicht, erzwinge Beendigung..." << std::endl; break; } } // Stoppe WebSocket Server std::cerr << "Stoppe WebSocket-Server..." << std::endl; websocketServer.stop(); // Stoppe Message Broker std::cerr << "Stoppe Message Broker..." << std::endl; broker.stop(); auto shutdownDuration = std::chrono::duration_cast( std::chrono::steady_clock::now() - shutdownStart); std::cerr << "Anwendung erfolgreich beendet in " << shutdownDuration.count() << "ms." << std::endl; // Erzwinge sofortiges Exit nach Shutdown std::cerr << "Erzwinge Prozess-Beendigung..." << std::endl; std::_Exit(0); } catch (const std::exception &e) { std::cerr << "Fehler: " << e.what() << std::endl; return 1; } return 0; }