Separate Connection, ConnectionHandler, Server
This commit is contained in:
136
src/server.hpp
Normal file
136
src/server.hpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.hpp"
|
||||
#include "connection_handler.hpp"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* High-performance multi-threaded server for handling network connections.
|
||||
*
|
||||
* The Server class encapsulates all networking logic including:
|
||||
* - Socket management and configuration
|
||||
* - Multi-threaded epoll-based I/O multiplexing
|
||||
* - Connection lifecycle management
|
||||
* - Graceful shutdown handling
|
||||
*
|
||||
* The server uses a configurable thread pool architecture:
|
||||
* - Accept threads: Handle incoming connections with load balancing
|
||||
* - Network threads: Process I/O events for established connections
|
||||
*
|
||||
* All protocol-specific logic is delegated to the provided ConnectionHandler,
|
||||
* maintaining clean separation between networking and application logic.
|
||||
*
|
||||
* IMPORTANT: Server uses a factory pattern and MUST be created via
|
||||
* Server::create(). This ensures:
|
||||
* - Proper shared_ptr semantics for enable_shared_from_this
|
||||
* - Safe weak_ptr references from Connection objects
|
||||
* - Prevention of accidental stack allocation that would break safety
|
||||
* guarantees
|
||||
*/
|
||||
class Server : public std::enable_shared_from_this<Server> {
|
||||
public:
|
||||
/**
|
||||
* Factory method to create a Server instance.
|
||||
*
|
||||
* This is the only way to create a Server - ensures proper shared_ptr
|
||||
* semantics and prevents accidental stack allocation that would break
|
||||
* weak_ptr safety.
|
||||
*
|
||||
* @param config Server configuration (threads, ports, limits, etc.)
|
||||
* @param handler Protocol handler for processing connection data
|
||||
* @return shared_ptr to the newly created Server
|
||||
*/
|
||||
static std::shared_ptr<Server> create(const weaseldb::Config &config,
|
||||
ConnectionHandler &handler);
|
||||
|
||||
/**
|
||||
* Destructor ensures proper cleanup of all resources.
|
||||
*/
|
||||
~Server();
|
||||
|
||||
/**
|
||||
* Start the server and begin accepting connections.
|
||||
*
|
||||
* This method:
|
||||
* - Creates and configures the listen socket
|
||||
* - Starts all worker threads
|
||||
* - Blocks until shutdown() is called or an error occurs
|
||||
*
|
||||
* @throws std::runtime_error on socket creation or configuration errors
|
||||
*/
|
||||
void run();
|
||||
|
||||
/**
|
||||
* Initiate graceful server shutdown.
|
||||
*
|
||||
* This method is async-signal-safe and can be called from signal handlers.
|
||||
* It signals all threads to stop processing and begin cleanup.
|
||||
*
|
||||
* The run() method will return after all threads have completed shutdown.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
* Release a connection back to its server for continued processing.
|
||||
*
|
||||
* This static method safely returns ownership of a connection back to its
|
||||
* server. If the server has been destroyed, the connection will be safely
|
||||
* cleaned up.
|
||||
*
|
||||
* This method is thread-safe and can be called from any thread.
|
||||
*
|
||||
* @param connection unique_ptr to the connection being released back
|
||||
*/
|
||||
static void releaseBackToServer(std::unique_ptr<Connection> connection);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Private constructor - use create() factory method instead.
|
||||
*
|
||||
* @param config Server configuration (threads, ports, limits, etc.)
|
||||
* @param handler Protocol handler for processing connection data
|
||||
*/
|
||||
explicit Server(const weaseldb::Config &config, ConnectionHandler &handler);
|
||||
|
||||
const weaseldb::Config &config_;
|
||||
ConnectionHandler &handler_;
|
||||
|
||||
// Thread management
|
||||
std::vector<std::thread> threads_;
|
||||
std::atomic<int64_t> connection_id_{0};
|
||||
|
||||
// Shutdown coordination
|
||||
int shutdown_pipe_[2] = {-1, -1};
|
||||
|
||||
// Epoll file descriptors
|
||||
int network_epollfd_ = -1;
|
||||
int accept_epollfd_ = -1;
|
||||
int listen_sockfd_ = -1;
|
||||
|
||||
// Private helper methods
|
||||
void setup_shutdown_pipe();
|
||||
void setup_signal_handling();
|
||||
int create_listen_socket();
|
||||
void start_network_threads();
|
||||
void start_accept_threads();
|
||||
void cleanup_resources();
|
||||
|
||||
/**
|
||||
* Called internally to return ownership to the server.
|
||||
*
|
||||
* This method is thread-safe and can be called from any thread.
|
||||
* The connection will be re-added to the epoll for continued processing.
|
||||
*
|
||||
* @param connection Raw pointer to the connection being released back
|
||||
*/
|
||||
void receiveConnectionBack(Connection *connection);
|
||||
|
||||
// Make non-copyable and non-movable
|
||||
Server(const Server &) = delete;
|
||||
Server &operator=(const Server &) = delete;
|
||||
Server(Server &&) = delete;
|
||||
Server &operator=(Server &&) = delete;
|
||||
};
|
||||
Reference in New Issue
Block a user