Ferenc Szontágh
2024-06-27 920507bff803647c79dfce27c4c265b2caee7f8d
src/Server.cpp
@@ -1,73 +1,123 @@
#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);
        }
@@ -75,19 +125,25 @@
    }
}
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);
    }