diff --git a/design.md b/design.md index d8a42fa..efd4ef5 100644 --- a/design.md +++ b/design.md @@ -135,7 +135,6 @@ Key features: Key features: - process_data() with unique_ptr& for ownership transfer -- ProcessResult enum for connection lifecycle control (Continue/CloseAfterSend/CloseNow) - on_connection_established/closed() hooks for protocol state management - Zero-copy data processing with arena allocator integration - Thread-safe ownership transfer via Server::releaseBackToServer() @@ -280,7 +279,6 @@ The modular design allows each component to be optimized independently while mai - Implement `process_data()` with proper ownership semantics - Use connection's arena allocator for temporary allocations: `conn->getArena()` - Handle partial messages and streaming protocols appropriately -- Return appropriate `ProcessResult` for connection lifecycle management - Use `Server::releaseBackToServer()` if taking ownership for async processing - Add corresponding test cases and integration tests - Consider performance implications of ownership transfers @@ -334,7 +332,7 @@ auto server = Server::create(config, handler); ```cpp class HttpHandler : public ConnectionHandler { public: - ProcessResult process_data(std::string_view data, std::unique_ptr& conn_ptr) override { + void process_data(std::string_view data, std::unique_ptr& conn_ptr) override { // Parse HTTP request using connection's arena ArenaAllocator& arena = conn_ptr->getArena(); @@ -342,7 +340,6 @@ public: conn_ptr->appendMessage("HTTP/1.1 200 OK\r\n\r\nHello World"); // Server retains ownership - return ProcessResult::CloseAfterSend; } }; ``` @@ -351,7 +348,7 @@ public: ```cpp class AsyncHandler : public ConnectionHandler { public: - ProcessResult process_data(std::string_view data, std::unique_ptr& conn_ptr) override { + void process_data(std::string_view data, std::unique_ptr& conn_ptr) override { // Take ownership for async processing auto connection = std::move(conn_ptr); // conn_ptr is now null @@ -362,8 +359,6 @@ public: // Return ownership to server when done Server::releaseBackToServer(std::move(connection)); }); - - return ProcessResult::Continue; // Server won't continue processing (conn_ptr is null) } }; ``` diff --git a/src/connection_handler.hpp b/src/connection_handler.hpp index 131112b..4cedeb0 100644 --- a/src/connection_handler.hpp +++ b/src/connection_handler.hpp @@ -6,12 +6,6 @@ // Forward declaration to avoid circular dependency struct Connection; -enum class ProcessResult { - Continue, // Keep connection open, continue processing - CloseAfterSend, // Send response then close connection - CloseNow // Close connection immediately -}; - /** * Abstract interface for handling connection data processing. * @@ -32,19 +26,17 @@ public: * @param data Incoming data buffer (may be partial message) * @param conn_ptr Unique pointer to connection - handler can take ownership * by releasing it - * @return ProcessResult indicating how to handle the connection * * Implementation should: * - Parse incoming data using arena allocator when needed * - Use conn_ptr->appendMessage() to queue response data - * - Return appropriate ProcessResult for connection management * - Handle partial messages and streaming protocols appropriately * - Can take ownership by calling conn_ptr.release() to pass to other threads * - If ownership is taken, handler must call Server::releaseBackToServer() * when done */ - virtual ProcessResult process_data(std::string_view data, - std::unique_ptr &conn_ptr) = 0; + virtual void process_data(std::string_view data, + std::unique_ptr &conn_ptr) = 0; /** * Called when a new connection is established. @@ -53,8 +45,6 @@ public: * * Use this for: * - Connection-specific initialization - * - Sending greeting messages - * - Setting up connection state */ virtual void on_connection_established(Connection &) {} @@ -65,8 +55,6 @@ public: * * Use this for: * - Cleanup of connection-specific resources - * - Logging connection statistics - * - Finalizing protocol state */ virtual void on_connection_closed(Connection &) {} }; diff --git a/src/main.cpp b/src/main.cpp index b019d52..51b729a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,10 +6,12 @@ #include #include +// TODO this should be scoped to a particular Server, and it's definition should +// be in server.cpp or connection.cpp std::atomic activeConnections{0}; // Global server instance for signal handler access -Server *g_server = nullptr; +static Server *g_server = nullptr; void signal_handler(int sig) { if (sig == SIGTERM || sig == SIGINT) { @@ -27,17 +29,10 @@ void signal_handler(int sig) { */ class EchoHandler : public ConnectionHandler { public: - ProcessResult process_data(std::string_view data, - std::unique_ptr &conn_ptr) override { + void process_data(std::string_view data, + std::unique_ptr &conn_ptr) override { // Echo the received data back to the client conn_ptr->appendMessage(data); - return ProcessResult::Continue; - } - - void on_connection_established(Connection &conn) override { - // Could send a welcome message if desired - // conn.appendMessage("Welcome to WeaselDB echo server\n"); - (void)conn; // Suppress unused parameter warning } }; diff --git a/src/server.cpp b/src/server.cpp index 78b458c..bca080f 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -270,17 +270,7 @@ void Server::start_network_threads() { // Call handler with unique_ptr - handler can take ownership if // needed - ProcessResult result = handler_.process_data(data, conn); - switch (result) { - case ProcessResult::Continue: - break; - case ProcessResult::CloseAfterSend: - conn->closeAfterSend(); - break; - case ProcessResult::CloseNow: - continue; // Connection will be destroyed when unique_ptr goes out - // of scope - } + handler_.process_data(data, conn); // If handler took ownership (conn is now null), don't continue // processing @@ -423,4 +413,4 @@ void Server::cleanup_resources() { close(listen_sockfd_); listen_sockfd_ = -1; } -} \ No newline at end of file +}