WIP
This commit is contained in:
@@ -30,28 +30,26 @@ struct Server;
|
||||
*/
|
||||
struct MessageSender {
|
||||
/**
|
||||
* @brief Append message data to connection's outgoing message queue.
|
||||
* @brief Send response with protocol-specific context for ordering.
|
||||
*
|
||||
* Thread-safe method that can be called from any thread, including
|
||||
* pipeline processing threads. The arena is moved into the connection
|
||||
* to maintain data lifetime until the message is sent. Messages appended
|
||||
* concurrently may be written in either order, but they will not be
|
||||
* interleaved.
|
||||
* Thread-safe method for pipeline threads to send responses back to clients.
|
||||
* Delegates to the connection's protocol handler for ordering logic.
|
||||
* The protocol handler may queue the response or send it immediately.
|
||||
*
|
||||
* @param data_parts Span of string_view parts to send (arena-allocated)
|
||||
* @param arena Arena containing the memory for data_parts string_views
|
||||
* @param close_after_send Whether to close connection after sending
|
||||
* @param protocol_context Arena-allocated protocol-specific context
|
||||
* @param data Response data parts (may be empty for deferred serialization)
|
||||
* @param arena Arena containing response data and context
|
||||
*
|
||||
* Example usage:
|
||||
* ```cpp
|
||||
* auto response_parts = arena.allocate_span<std::string_view>(2);
|
||||
* response_parts[0] = "HTTP/1.1 200 OK\r\n\r\n";
|
||||
* response_parts[1] = "Hello World";
|
||||
* conn.append_message(response_parts, std::move(arena));
|
||||
* auto* ctx = arena.allocate<HttpResponseContext>();
|
||||
* ctx->sequence_id = 42;
|
||||
* auto response_data = format_response(arena);
|
||||
* conn.send_response(ctx, response_data, std::move(arena));
|
||||
* ```
|
||||
*/
|
||||
virtual void append_message(std::span<std::string_view> data_parts,
|
||||
Arena arena, bool close_after_send = false) = 0;
|
||||
virtual void send_response(void *protocol_context,
|
||||
std::string_view response_json, Arena arena) = 0;
|
||||
|
||||
virtual ~MessageSender() = default;
|
||||
};
|
||||
@@ -104,31 +102,33 @@ struct Connection : MessageSender {
|
||||
* @brief Queue an atomic message to be sent to the client.
|
||||
*
|
||||
* Adds a complete message with all associated data to the connection's
|
||||
* outgoing message queue. The message will be sent asynchronously by a
|
||||
* server I/O thread using efficient vectored I/O.
|
||||
* outgoing byte queue with guaranteed ordering.
|
||||
*
|
||||
* I/O thread only method for protocol handlers to queue bytes for sending.
|
||||
* Bytes are queued in order and sent using efficient vectored I/O.
|
||||
*
|
||||
* @param data_parts Span of string_views pointing to arena-allocated data
|
||||
* @param arena Arena that owns all the memory referenced by data_parts
|
||||
* @param close_after_send Whether to close connection after sending this
|
||||
* message
|
||||
*
|
||||
* @note Thread Safety: This method is thread-safe and can be called
|
||||
* concurrently from multiple pipeline threads.
|
||||
* @param close_after_send Whether to close connection after sending
|
||||
*
|
||||
* @note Thread Safety: Must be called from I/O thread only.
|
||||
* @note Ordering: Bytes are sent in the order calls are made.
|
||||
* @note The memory referenced by the data_parts span, must outlive @p arena.
|
||||
* The arena will be moved and kept alive until the message is fully sent.
|
||||
*
|
||||
* Example usage:
|
||||
* Example usage (from ConnectionHandler::on_preprocess_writes):
|
||||
* ```cpp
|
||||
* Arena arena;
|
||||
* auto parts = arena.allocate_span<std::string_view>(2);
|
||||
* parts[0] = build_header(arena);
|
||||
* parts[1] = build_body(arena);
|
||||
* conn.append_message({parts, 2}, std::move(arena));
|
||||
* conn.append_bytes({parts, 2}, std::move(arena), false);
|
||||
* ```
|
||||
*/
|
||||
void append_message(std::span<std::string_view> data_parts, Arena arena,
|
||||
bool close_after_send) override;
|
||||
void append_bytes(std::span<std::string_view> data_parts, Arena arena,
|
||||
bool close_after_send);
|
||||
|
||||
void send_response(void *protocol_context, std::string_view response_json,
|
||||
Arena arena) override;
|
||||
|
||||
/**
|
||||
* @brief Get a WeakRef to this connection for async operations.
|
||||
@@ -342,6 +342,10 @@ private:
|
||||
// mutex_, but if non-empty mutex_ can be
|
||||
// dropped while server accesses existing elements.
|
||||
int64_t outgoing_bytes_queued_{0}; // Counter of queued bytes
|
||||
bool has_pending_responses_{
|
||||
false}; // True if protocol handler has responses to process
|
||||
std::deque<PendingResponse>
|
||||
pending_response_queue_; // Responses awaiting protocol processing
|
||||
// Set to a negative number in `close`
|
||||
int fd_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user