| | |
| | | #include "Server.h" |
| | | #include <iostream> |
| | | #include <csignal> |
| | | #include <chrono> |
| | | |
| | | // Initialize the static instance pointer |
| | | Server* Server::instance = nullptr; |
| | | Server *Server::instance = nullptr; |
| | | |
| | | Server::Server() : reloadConfigFlag(false) { |
| | | Server::Server() : reloadConfigFlag(false) |
| | | { |
| | | instance = this; // Set the instance pointer |
| | | ipc = std::make_unique<IPC>(); |
| | | signal(SIGUSR1, Server::handleSignal); |
| | | if (!config.loadFromFile("config.json")) { |
| | | if (!config.loadFromFile("/etc/fserver/config.json")) |
| | | { |
| | | std::cerr << "Failed to load config.json" << std::endl; |
| | | } |
| | | loadPlugins(); |
| | | for (int i = 0; i < 4; ++i) { |
| | | threadPool.emplace_back(std::make_unique<std::thread>(&Server::handleIPC, this)); |
| | | for (int i = 0; i < 4; ++i) |
| | | { |
| | | threadPool.emplace_back(&Server::handleIPC, this); |
| | | } |
| | | } |
| | | |
| | | Server::~Server() { |
| | | for (auto& handle : pluginHandles) { |
| | | 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() { |
| | | Server &Server::getInstance() |
| | | { |
| | | return *instance; |
| | | } |
| | | |
| | | void Server::run() { |
| | | void Server::run() |
| | | { |
| | | mainLoop(); |
| | | } |
| | | |
| | | void Server::reloadConfig() { |
| | | if (config.loadFromFile("config.json")) { |
| | | std::cout << "Configuration reloaded." << std::endl; |
| | | for (auto& plugin : plugins) { |
| | | plugin->updateConfig(config.getConfig()); |
| | | void Server::reloadConfig() |
| | | { |
| | | if (config.loadFromFile("/etc/fserver/config.json")) |
| | | { |
| | | // std::cout << "Configuration reloaded." << std::endl; |
| | | LOG(INFO) << "Configuration reloaded /etc/fserver/config.json"; |
| | | |
| | | // Stop and clear existing plugins |
| | | for (auto &plugin : plugins) |
| | | { |
| | | plugin->updateConfig({}); // Optionally reset plugin config |
| | | } |
| | | } else { |
| | | std::cerr << "Failed to reload configuration." << std::endl; |
| | | 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() { |
| | | const char* pluginPath = "./plugins/libSamplePlugin.so"; |
| | | void* handle = dlopen(pluginPath, RTLD_LAZY); |
| | | if (!handle) { |
| | | std::cerr << "Cannot open library: " << dlerror() << '\n'; |
| | | return; |
| | | } |
| | | pluginHandles.push_back(handle); |
| | | void Server::loadPlugins() |
| | | { |
| | | auto configData = config.getConfig(); |
| | | auto pluginsArray = configData["plugins"]; |
| | | for (const auto &pluginName : pluginsArray) |
| | | { |
| | | std::string pluginPath = "./plugins/" + pluginName.get<std::string>(); |
| | | 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)(); |
| | | create_t create_plugin = (create_t)dlsym(handle, "create"); |
| | | const char* dlsym_error = dlerror(); |
| | | if (dlsym_error) { |
| | | std::cerr << "Cannot load symbol create: " << dlsym_error << '\n'; |
| | | return; |
| | | } |
| | | 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<IPlugin> plugin(create_plugin()); |
| | | plugins.push_back(plugin); |
| | | ipc.registerHandler(plugin); |
| | | plugin->updateConfig(config.getConfig()); // Forward the config to the plugin |
| | | std::shared_ptr<IPlugin> 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()) { |
| | | void Server::mainLoop() |
| | | { |
| | | while (true) |
| | | { |
| | | if (reloadConfigFlag.load()) |
| | | { |
| | | reloadConfig(); |
| | | reloadConfigFlag.store(false); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | void Server::handleIPC() { |
| | | while (true) { |
| | | auto message = ipc.receiveMessage(); |
| | | if (message.has_value()) { |
| | | for (auto& plugin : plugins) { |
| | | 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) { |
| | | void Server::handleSignal(int signal) |
| | | { |
| | | if (signal == SIGUSR1) |
| | | { |
| | | std::cout << "Received signal to reload configuration." << std::endl; |
| | | Server::getInstance().reloadConfigFlag.store(true); |
| | | } |