#include #include #include "webserver_service.hpp" #include "logging/logger.hpp" #include "config/config_loader.hpp" #include "common/config_arg.hpp" using namespace smartbotic; std::atomic g_shutdown{false}; void signalHandler(int signal) { LOG_INFO("Received signal {}, shutting down...", signal); g_shutdown = true; } int main(int argc, char* argv[]) { // Initialize logging logging::LogConfig log_config; log_config.name = "webserver"; log_config.level = logging::LogLevel::Info; logging::Logger::init(log_config); LOG_INFO("SmartBotic WebServer starting..."); // Load configuration const auto config_arg = common::parseConfigArg(argc, argv, "./config/webserver.json"); const std::filesystem::path config_path = config_arg.path; webserver::WebServerServiceConfig config; if (std::filesystem::exists(config_path)) { config = webserver::WebServerService::loadConfig(config_path); LOG_INFO("Loaded configuration from {}", config_path.string()); } else if (config_arg.explicitly_given) { // Someone named this file, so starting on defaults would run the // service against a different database, project namespace and port // than they asked for - and the only sign would be a warning nobody // reads. Refuse to start instead. LOG_ERROR("Config file not found at {}. It was given on the command line, " "so refusing to start on built-in defaults", config_path.string()); return 1; } else { LOG_WARN("Config file not found at {}, using defaults", config_path.string()); } // Setup signal handlers std::signal(SIGINT, signalHandler); std::signal(SIGTERM, signalHandler); // Create and start service webserver::WebServerService service(config); try { service.start(); // Wait for shutdown signal while (!g_shutdown) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } service.stop(); } catch (const std::exception& e) { LOG_ERROR("Fatal error: {}", e.what()); return 1; } LOG_INFO("SmartBotic WebServer stopped"); logging::Logger::shutdown(); return 0; }