From 05e22fbac2fd96eab898f065137762af52506793 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Tue, 19 Aug 2025 15:39:10 -0400 Subject: [PATCH] Add batching handler and streaming handler examples --- design.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/design.md b/design.md index 0f35db0..44dd28f 100644 --- a/design.md +++ b/design.md @@ -126,6 +126,7 @@ Key features: - Private networking details accessible only to Server via friend relationship - Public handler interface: appendMessage(), closeAfterSend(), getArena(), getId() - Thread-safe ownership transfer with Server::releaseBackToServer() +- **Protocol-specific data**: `user_data` `void*` for custom handler data. #### 9. **ConnectionHandler Interface** (`src/connection_handler.hpp`) - **Abstract protocol interface** decoupling networking from application logic @@ -136,6 +137,7 @@ Key features: Key features: - on_data_arrived()/on_write_progress() with unique_ptr& for ownership transfer - on_connection_established/closed() hooks for protocol state management +- on_post_batch(): Hook for batch processing of connections after I/O - Zero-copy data processing with arena allocator integration - Thread-safe ownership transfer via Server::releaseBackToServer() @@ -368,7 +370,63 @@ public: }; ``` -TODO add example of streaming data +#### Batching Handler with User Data +```cpp +class BatchingHandler : public ConnectionHandler { +public: + void on_connection_established(Connection &conn) override { + // Allocate some protocol-specific data and attach it to the connection + conn.user_data = new MyProtocolData(); + } + + void on_connection_closed(Connection &conn) override { + // Free the protocol-specific data + delete static_cast(conn.user_data); + } + + void on_data_arrived(std::string_view data, + std::unique_ptr &conn_ptr) override { + // Process data and maybe store some results in the user_data + auto* proto_data = static_cast(conn_ptr->user_data); + proto_data->process(data); + } + + void on_post_batch(std::span> batch) override { + // Process a batch of connections + for (auto& conn_ptr : batch) { + if (conn_ptr) { + auto* proto_data = static_cast(conn_ptr->user_data); + if (proto_data->is_ready()) { + // This connection is ready for the next stage, move it to the pipeline + pipeline_.push(std::move(conn_ptr)); + } + } + } + } + +private: + MyProcessingPipeline pipeline_; +}; +``` + +#### Streaming "yes" Handler +```cpp +class YesHandler : public ConnectionHandler { +public: + void on_connection_established(Connection &conn) override { + // Start writing immediately + on_write_progress(conn); + } + + void on_write_progress(std::unique_ptr &conn_ptr) override { + // Write "y\n" repeatedly + if (conn_ptr->outgoingBytesQueued() == 0) + conn_ptr->appendMessage("y\n"); + } + } +}; +``` + ### Arena-Based String Handling ```cpp