Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
flow_control.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
8
9#include <cstdint>
10#include <optional>
11
13{
14
18namespace flow_control_error
19{
20 constexpr int send_blocked = -710;
21 constexpr int receive_overflow = -711;
22 constexpr int window_exceeded = -712;
23} // namespace flow_control_error
24
34{
35public:
40 explicit flow_controller(uint64_t initial_window = 1048576);
41
42 ~flow_controller() = default;
43
44 // Copyable
46 auto operator=(const flow_controller&) -> flow_controller& = default;
47
48 // Movable
49 flow_controller(flow_controller&&) noexcept = default;
50 auto operator=(flow_controller&&) noexcept -> flow_controller& = default;
51
52 // ========================================================================
53 // Send Side (Connection-level limits on our sending)
54 // ========================================================================
55
60 [[nodiscard]] auto available_send_window() const noexcept -> uint64_t;
61
67 [[nodiscard]] auto consume_send_window(uint64_t bytes) -> VoidResult;
68
73 void update_send_limit(uint64_t max_data);
74
78 [[nodiscard]] auto is_send_blocked() const noexcept -> bool;
79
83 [[nodiscard]] auto send_limit() const noexcept -> uint64_t { return send_limit_; }
84
88 [[nodiscard]] auto bytes_sent() const noexcept -> uint64_t { return bytes_sent_; }
89
90 // ========================================================================
91 // Receive Side (Connection-level limits on peer's sending)
92 // ========================================================================
93
99 [[nodiscard]] auto record_received(uint64_t bytes) -> VoidResult;
100
105 void record_consumed(uint64_t bytes);
106
110 [[nodiscard]] auto receive_limit() const noexcept -> uint64_t { return receive_limit_; }
111
115 [[nodiscard]] auto bytes_received() const noexcept -> uint64_t { return bytes_received_; }
116
120 [[nodiscard]] auto bytes_consumed() const noexcept -> uint64_t { return bytes_consumed_; }
121
122 // ========================================================================
123 // Flow Control Frame Generation
124 // ========================================================================
125
129 [[nodiscard]] auto should_send_max_data() const noexcept -> bool;
130
135 [[nodiscard]] auto generate_max_data() -> std::optional<uint64_t>;
136
140 [[nodiscard]] auto should_send_data_blocked() const noexcept -> bool;
141
146
147 // ========================================================================
148 // Configuration
149 // ========================================================================
150
155 void set_window_size(uint64_t window);
156
160 [[nodiscard]] auto window_size() const noexcept -> uint64_t { return window_size_; }
161
166 void set_update_threshold(double threshold);
167
168 // ========================================================================
169 // Reset
170 // ========================================================================
171
176 void reset(uint64_t initial_window);
177
178private:
179 // Send side (peer's limits on us)
180 uint64_t send_limit_{0}; // Peer's MAX_DATA (our send limit)
181 uint64_t bytes_sent_{0}; // Total bytes we've sent
182 bool data_blocked_sent_{false}; // DATA_BLOCKED already sent
183
184 // Receive side (our limits on peer)
185 uint64_t receive_limit_{0}; // Our MAX_DATA (peer's send limit)
186 uint64_t bytes_received_{0}; // Total bytes received
187 uint64_t bytes_consumed_{0}; // Bytes consumed by application
188
189 // Window management
190 uint64_t window_size_;
191 double update_threshold_{0.5}; // Send MAX_DATA when 50% consumed
192
193 // Track if we need to send MAX_DATA
195};
196
202{
203 // Send side
204 uint64_t send_limit{0};
205 uint64_t bytes_sent{0};
207 bool send_blocked{false};
208
209 // Receive side
210 uint64_t receive_limit{0};
211 uint64_t bytes_received{0};
212 uint64_t bytes_consumed{0};
214};
215
221[[nodiscard]] auto get_flow_control_stats(const flow_controller& fc) -> flow_control_stats;
222
223} // namespace kcenon::network::protocols::quic
Connection-level flow control for QUIC (RFC 9000 Section 4)
auto should_send_max_data() const noexcept -> bool
Check if MAX_DATA frame should be sent.
auto bytes_consumed() const noexcept -> uint64_t
Get bytes consumed by application.
void update_send_limit(uint64_t max_data)
Update the send limit (from peer's MAX_DATA)
auto record_received(uint64_t bytes) -> VoidResult
Record received data.
flow_controller(uint64_t initial_window=1048576)
Construct a flow controller.
auto receive_limit() const noexcept -> uint64_t
Get our receive limit (advertised as MAX_DATA)
flow_controller(const flow_controller &)=default
auto is_send_blocked() const noexcept -> bool
Check if send is blocked.
void record_consumed(uint64_t bytes)
Record data consumed by application.
auto available_send_window() const noexcept -> uint64_t
Get available send window.
flow_controller(flow_controller &&) noexcept=default
auto should_send_data_blocked() const noexcept -> bool
Check if DATA_BLOCKED frame should be sent.
auto bytes_sent() const noexcept -> uint64_t
Get total bytes sent.
void mark_data_blocked_sent()
Mark DATA_BLOCKED as sent (to avoid repeated sending)
auto consume_send_window(uint64_t bytes) -> VoidResult
Try to consume send window for outgoing data.
auto send_limit() const noexcept -> uint64_t
Get the current send limit (peer's MAX_DATA)
void reset(uint64_t initial_window)
Reset flow controller state.
void set_update_threshold(double threshold)
Set the threshold for sending MAX_DATA updates (0.0 - 1.0)
auto bytes_received() const noexcept -> uint64_t
Get total bytes received.
auto generate_max_data() -> std::optional< uint64_t >
Generate MAX_DATA value if update needed.
auto operator=(const flow_controller &) -> flow_controller &=default
auto window_size() const noexcept -> uint64_t
Get the current window size.
void set_window_size(uint64_t window)
Set the window size for auto-tuning.
auto get_flow_control_stats(const flow_controller &fc) -> flow_control_stats
Get flow control statistics.
Result< std::monostate > VoidResult
Network-specific error and result type definitions.
Statistics for flow control monitoring.