#pragma once #include #include // Forward declarations to avoid circular dependency struct Connection; // Include Arena header since PendingResponse uses Arena by value #include "arena.hpp" /** * Represents a response queued by pipeline threads for protocol processing. * Contains JSON response data that can be wrapped by any protocol. */ struct PendingResponse { void *protocol_context; // Arena-allocated protocol-specific context std::string_view response_json; // JSON response body (arena-allocated) Arena arena; // Arena containing response data and context }; /** * 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 Connection reference - server retains ownership * * Implementation should: * - Create request-scoped Arena for parsing and response generation * - Parse incoming data using the request arena * - Use conn.append_message() to queue response data to be sent * - Handle partial messages and streaming protocols appropriately * - Use conn.get_weak_ref() for async processing if needed * * @note `data` lifetime ends after the call to on_data_arrived. * @note Called from this connection's io thread. * @note Handler can safely access connection concurrently via thread-safe * methods. */ virtual void on_data_arrived(std::string_view /*data*/, Connection &) {}; /** * 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 Connection that made write progress - server retains ownership * @note Called from this connection's io thread. * @note Called during writes, not necessarily when buffer becomes empty * TODO Add bytes written argument? */ virtual void on_write_progress(Connection &) {} /** * Called when a new connection is established. * * @param conn Newly established connection * * Use this for: * - Connection-specific initialization. * @note Called from this connection's io 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 Called from this connection's io thread, or possibly a foreign thread * that has locked the MessageSender associated with this connection. */ virtual void on_connection_closed(Connection &) {} /** * @brief Called after a batch of connections has been processed. * * This hook is called after on_data_arrived or on_write_progress has been * called for each connection in the batch. All connections remain * server-owned. * * @param batch A span of connection references in the batch. * @note Called from this connection's io thread. */ virtual void on_batch_complete(std::span /*batch*/) {} /** * Called before processing outgoing writes on a connection. * * This hook allows protocol handlers to process queued responses * before actual socket writes occur. Used for response ordering, * serialization, and other preprocessing. * * @param conn Connection about to write data * @param pending_responses Responses queued by pipeline threads * @note Called from this connection's io thread. * @note Called when EPOLLOUT event occurs */ virtual void on_preprocess_writes(Connection &conn, std::span pending_responses) {} };