#pragma once #include #include #include // Forward declaration to avoid circular dependency struct Connection; /** * Abstract interface for handling connection data processing. * * This interface decouples protocol-specific logic (HTTP, WebSocket, etc.) * from the underlying networking infrastructure. Implementations handle * parsing incoming data and generating appropriate responses. * * The networking layer manages connection lifecycle, I/O multiplexing, * and efficient data transfer, while handlers focus purely on protocol logic. */ struct ConnectionHandler { public: virtual ~ConnectionHandler() = default; /** * Process incoming data from a connection. * * @param data Incoming data buffer (may be partial message) * @param conn_ptr Unique pointer to connection - handler can take ownership * by releasing it * * Implementation should: * - Parse incoming data using arena allocator when needed * - Use conn_ptr->appendMessage() to queue response data to be sent * - 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 * @note `data` is *not* owned by the connection arena, and its lifetime ends * after the call to on_data_arrived. * @note May be called from an arbitrary server thread. */ virtual void on_data_arrived(std::string_view /*data*/, std::unique_ptr &) {}; /** * Called when data has been successfully written to the connection. * * This is called during write operations to indicate progress, useful for: * - Streaming large responses (files, data feeds, etc.) * - Implementing backpressure for continuous data streams * - Progress monitoring for long-running transfers * * @param conn_ptr Connection that made write progress - handler can take * ownership * @note May be called from an arbitrary server thread. * @note Called during writes, not necessarily when buffer becomes empty */ virtual void on_write_progress(std::unique_ptr &) {} /** * Called when the connection's outgoing write buffer becomes empty. * * This indicates all queued messages have been successfully written * to the socket. Useful for: * - Resetting arena allocators safely * - Implementing keep-alive connection reuse * - Closing connections after final response * - Relieving backpressure conditions * * @param conn_ptr Connection with empty write buffer - handler can take * ownership * @note May be called from an arbitrary server thread. * @note Only called on transitions from non-empty → empty buffer */ virtual void on_write_buffer_drained(std::unique_ptr &) {} /** * Called when a new connection is established. * * @param conn Newly established connection * * Use this for: * - Connection-specific initialization. * @note May be called from an arbitrary server thread. */ virtual void on_connection_established(Connection &) {} /** * Called when a connection is about to be closed. * * @param conn Connection being closed * * Use this for: * - Cleanup of connection-specific resources. * @note May be called from an arbitrary server thread. */ virtual void on_connection_closed(Connection &) {} /** * @brief Called after a batch of connections has been processed. * * This hook is called after on_data_arrived, on_write_progress, or * on_write_buffer_drained has been called for each connection in the batch. * The handler can take ownership of the connections by moving the unique_ptr * out of the span. Any connections left in the span will remain owned by the * server. * * @param batch A span of unique_ptrs to the connections in the batch. */ virtual void on_batch_complete(std::span> /*batch*/) {} };