#include "Server.h"
|
#include <iostream>
|
#include <csignal>
|
#include <chrono>
|
|
// Initialize the static instance pointer
|
Server *Server::instance = nullptr;
|
|
Server::Server() : reloadConfigFlag(false)
|
{
|
instance = this; // Set the instance pointer
|
ipc = std::make_unique<IPC>();
|
signal(SIGUSR1, Server::handleSignal);
|
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(&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"))
|
{
|
// 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
|
}
|
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<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)(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(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)
|
{
|
std::cout << "Received signal to reload configuration." << std::endl;
|
Server::getInstance().reloadConfigFlag.store(true);
|
}
|
}
|