#include "Server.h" #include #include #include // Initialize the static instance pointer Server *Server::instance = nullptr; Server::Server() : reloadConfigFlag(false) { instance = this; // Set the instance pointer ipc = std::make_unique(); signal(SIGUSR1, Server::handleSignal); if (!config.loadFromFile("/etc/fserver/config.json")) { LOG(ERROR) << "Failed to load /etc/fserver/config.json"; } loadPlugins(); for (int i = 0; i < 4; ++i) { threadPool.emplace_back(&Server::handleIPC, this); } } Server::~Server() { // Join all threads for (auto &thread : threadPool) { if (thread.joinable()) { thread.join(); } } // Close all plugin handles for (auto &handle : pluginHandles) { dlclose(handle); } } Server &Server::getInstance() { return *instance; } void Server::run() { mainLoop(); } void Server::reloadConfig() { if (config.loadFromFile("/etc/fserver/config.json")) { LOG(INFO) << "Configuration reloaded /etc/fserver/config.json"; // Stop and clear existing plugins for (auto &plugin : plugins) { plugin->updateConfig({}); // Optionally reset plugin config } plugins.clear(); // Close and clear plugin handles for (auto &handle : pluginHandles) { dlclose(handle); } pluginHandles.clear(); loadPlugins(); } else { LOG(ERROR) << "Failed to reload configuration"; } } void Server::loadPlugins() { auto configData = config.getConfig(); auto pluginsArray = configData["plugins"]; for (const auto &pluginName : pluginsArray) { std::string pluginPath = "./plugins/" + pluginName.get(); void *handle = dlopen(pluginPath.c_str(), RTLD_LAZY); if (!handle) { LOG(WARNING) << "Can not open lib: " << dlerror(); continue; } pluginHandles.push_back(handle); typedef IPlugin *(*create_t)(IPC *); create_t create_plugin = (create_t)dlsym(handle, "create"); const char *dlsym_error = dlerror(); if (dlsym_error) { LOG(ERROR) << "Cannot load symbol create: " << dlsym_error; dlclose(handle); continue; } std::shared_ptr plugin(create_plugin(ipc.get())); plugins.push_back(plugin); ipc->registerHandler(plugin); plugin->updateConfig(config.getConfig()); // Forward the config to the plugin LOG(INFO) << "Plugin loaded: " << plugin->getPluginName(); } } void Server::mainLoop() { while (true) { if (reloadConfigFlag.load()) { reloadConfig(); reloadConfigFlag.store(false); } std::this_thread::sleep_for(std::chrono::seconds(1)); } } void Server::handleIPC() { while (true) { auto message = ipc->receiveMessage(); if (message.has_value()) { for (auto &plugin : plugins) { plugin->handleMessage(message.value()); } } } } void Server::handleSignal(int signal) { if (signal == SIGUSR1) { LOG(INFO) << "Reloading config file by SIGUSR1"; Server::getInstance().reloadConfigFlag.store(true); } }