LCOV - code coverage report
Current view: top level - wirestead/transport/tcp_server - tcp_server_session.hpp (source / functions) Coverage Total Hit
Test: Wirestead Coverage Report Lines: 100.0 % 1 1
Test Date: 2026-08-30 10:35:09 Functions: 100.0 % 1 1
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * Copyright 2025 Jinwoo Sung
       3                 :             :  *
       4                 :             :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :             :  * you may not use this file except in compliance with the License.
       6                 :             :  * You may obtain a copy of the License at
       7                 :             :  *
       8                 :             :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :             :  *
      10                 :             :  * Unless required by applicable law or agreed to in writing, software
      11                 :             :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :             :  * See the License for the specific language governing permissions and
      14                 :             :  * limitations under the License.
      15                 :             :  */
      16                 :             : 
      17                 :             : #pragma once
      18                 :             : 
      19                 :             : #include <array>
      20                 :             : #include <atomic>
      21                 :             : #include <boost/asio.hpp>
      22                 :             : #include <cstdint>
      23                 :             : #include <deque>
      24                 :             : #include <functional>
      25                 :             : #include <memory>
      26                 :             : #include <mutex>
      27                 :             : #include <optional>
      28                 :             : #include <variant>
      29                 :             : #include <vector>
      30                 :             : 
      31                 :             : #include "wirestead/base/constants.hpp"
      32                 :             : #include "wirestead/base/platform.hpp"
      33                 :             : #include "wirestead/base/visibility.hpp"
      34                 :             : #include "wirestead/diagnostics/error_handler.hpp"
      35                 :             : #include "wirestead/diagnostics/logger.hpp"
      36                 :             : #include "wirestead/diagnostics/runtime_stats_counter.hpp"
      37                 :             : #include "wirestead/interface/channel.hpp"
      38                 :             : #include "wirestead/interface/itcp_socket.hpp"
      39                 :             : #include "wirestead/memory/memory_pool.hpp"
      40                 :             : #include "wirestead/memory/safe_span.hpp"
      41                 :             : #include "wirestead/transport/base/bp_state_machine.hpp"
      42                 :             : 
      43                 :             : namespace wirestead {
      44                 :             : namespace transport {
      45                 :             : 
      46                 :             : namespace net = boost::asio;
      47                 :             : 
      48                 :             : using base::LinkState;
      49                 :             : using interface::TcpSocketInterface;
      50                 :             : using tcp = net::ip::tcp;
      51                 :             : 
      52                 :             : class WIRESTEAD_API TcpServerSession : public std::enable_shared_from_this<TcpServerSession> {
      53                 :             :  public:
      54                 :             :   using OnBytes = interface::Channel::OnBytes;
      55                 :             :   using OnBackpressure = interface::Channel::OnBackpressure;
      56                 :             :   using OnClose = std::function<void()>;
      57                 :             :   using BufferVariant =
      58                 :             :       std::variant<memory::PooledBuffer, std::vector<uint8_t>, std::shared_ptr<const std::vector<uint8_t>>>;
      59                 :             : 
      60                 :             :   TcpServerSession(net::io_context& ioc, tcp::socket sock,
      61                 :             :                    size_t backpressure_threshold = base::constants::DEFAULT_BACKPRESSURE_THRESHOLD,
      62                 :             :                    int idle_timeout_ms = 0,
      63                 :             :                    base::constants::BackpressureStrategy strategy = base::constants::BackpressureStrategy::Reliable,
      64                 :             :                    bool enable_memory_pool = true, size_t read_buffer_size = base::constants::DEFAULT_READ_BUFFER_SIZE);
      65                 :             :   // Constructor for testing with dependency injection
      66                 :             :   TcpServerSession(net::io_context& ioc, std::unique_ptr<interface::TcpSocketInterface> socket,
      67                 :             :                    size_t backpressure_threshold = base::constants::DEFAULT_BACKPRESSURE_THRESHOLD,
      68                 :             :                    int idle_timeout_ms = 0,
      69                 :             :                    base::constants::BackpressureStrategy strategy = base::constants::BackpressureStrategy::Reliable,
      70                 :             :                    bool enable_memory_pool = true, size_t read_buffer_size = base::constants::DEFAULT_READ_BUFFER_SIZE);
      71                 :             : 
      72                 :             :   void start();
      73                 :             :   bool async_write_copy(memory::ConstByteSpan data);
      74                 :             :   bool async_write_move(std::vector<uint8_t>&& data);
      75                 :             :   bool async_write_shared(std::shared_ptr<const std::vector<uint8_t>> data);
      76                 :             :   bool async_try_write_copy(memory::ConstByteSpan data);
      77                 :             :   bool async_try_write_move(std::vector<uint8_t>&& data);
      78                 :             :   bool async_try_write_shared(std::shared_ptr<const std::vector<uint8_t>> data);
      79                 :             :   void on_bytes(OnBytes cb);
      80                 :             :   void on_backpressure(OnBackpressure cb);
      81                 :             :   void on_close(OnClose cb);
      82                 :             :   bool alive() const;
      83                 :          12 :   bool is_backpressure_active() const { return backpressure_active_.load(); }
      84                 :             :   wrapper::RuntimeStats stats() const;
      85                 :             :   void reset_stats();
      86                 :             :   void stop();
      87                 :             :   void cancel();
      88                 :             : 
      89                 :             :  private:
      90                 :             :   void start_read();
      91                 :             :   void do_write();
      92                 :             :   void do_close();
      93                 :             :   void report_backpressure(size_t queued_bytes);
      94                 :             :   void reset_idle_timer();
      95                 :             :   void observe_queue();
      96                 :             :   // Shared decide_enqueue()/route dispatch used by all 3 async_write_* variants (#434).
      97                 :             :   void route_enqueued_buffer(BufferVariant&& buf, size_t added);
      98                 :             :   queue_util::BackpressureFields bp_fields();
      99                 :             : 
     100                 :             :  private:
     101                 :             :   net::io_context& ioc_;
     102                 :             :   net::strand<net::io_context::executor_type> strand_;
     103                 :             :   net::steady_timer idle_timer_;
     104                 :             :   std::unique_ptr<interface::TcpSocketInterface> socket_;
     105                 :             :   // #443: per-session pool instead of the process-wide GlobalMemoryPool
     106                 :             :   // singleton - avoids cross-channel contention on the singleton's bucket
     107                 :             :   // mutexes. Capacity is much smaller than the old shared default since
     108                 :             :   // it's no longer amortized across every connected client in the process.
     109                 :             :   // Prefill stays 0. This literal was written while MemoryPool discarded
     110                 :             :   // initial_pool_size, so 50 allocated nothing; #575 made the parameter real
     111                 :             :   // and turned it into ~1 MiB eagerly allocated per accepted session, on the
     112                 :             :   // accept handler itself. The pool fills as buffers are released.
     113                 :             :   memory::MemoryPool pool_{0, 200};
     114                 :             :   bool enable_memory_pool_ = true;
     115                 :             :   // Sized from the server's read_buffer_size rather than being a fixed
     116                 :             :   // std::array: this buffer exists per connection, so a server trades memory
     117                 :             :   // against read completions here with max_connections as the multiplier.
     118                 :             :   std::vector<uint8_t> rx_;
     119                 :             :   std::deque<BufferVariant> tx_;
     120                 :             :   std::deque<BufferVariant> pending_;
     121                 :             :   std::atomic<size_t> pending_bytes_{0};
     122                 :             :   // Buffers handed to the in-flight gather write; `current_write_views_`
     123                 :             :   // points into the batch, so neither is touched while a write is in flight.
     124                 :             :   std::vector<BufferVariant> current_write_batch_;
     125                 :             :   std::vector<net::const_buffer> current_write_views_;
     126                 :             :   bool writing_ = false;
     127                 :             :   std::atomic<size_t> queue_bytes_{0};
     128                 :             :   // Bytes accepted by a plain async_write_* call but not yet routed onto the
     129                 :             :   // strand - reserved via try_reserve_limit_bytes() to close the
     130                 :             :   // accept-then-drop race (jwsung91/wirestead#517). inflight_bytes_ mutations
     131                 :             :   // and the queue_bytes_/pending_bytes_ increments that promote a
     132                 :             :   // reservation both go through write_reserve_mtx_ - see bp_utils.hpp.
     133                 :             :   std::atomic<size_t> inflight_bytes_{0};
     134                 :             :   std::mutex write_reserve_mtx_;
     135                 :             :   base::constants::BackpressureStrategy bp_strategy_{base::constants::BackpressureStrategy::Reliable};
     136                 :             :   size_t bp_high_;   // Configurable backpressure threshold
     137                 :             :   size_t bp_limit_;  // Hard cap for queued bytes
     138                 :             :   size_t bp_low_;    // Backpressure relief threshold
     139                 :             :   std::atomic<bool> backpressure_active_{false};
     140                 :             :   diagnostics::RuntimeStatsCounters stats_;
     141                 :             :   int idle_timeout_ms_ = 0;
     142                 :             : 
     143                 :             :   OnBytes on_bytes_;
     144                 :             :   OnBackpressure on_bp_;
     145                 :             :   OnClose on_close_;
     146                 :             :   std::atomic<bool> alive_{false};
     147                 :             :   std::atomic<bool> closing_{false};
     148                 :             :   std::atomic<bool> cleanup_done_{false};
     149                 :             : };
     150                 :             : }  // namespace transport
     151                 :             : }  // namespace wirestead
        

Generated by: LCOV version 2.0-1