Flow control
HTTP/2 defines two levels of flow control (RFC 9113 §5.2): the connection-level window and a per-stream window. PureHTTP2.jl models both as FlowControlWindow instances. The FlowController ties them together — it owns one connection window and a dictionary of stream windows keyed by stream ID, and its operations correctly decrement both windows when a stream sends or receives DATA.
Above that, DataSender and DataReceiver layer frame-size limits on top of the flow controller, splitting outgoing DATA into frames no larger than the peer's MAX_FRAME_SIZE.
Role signalling
Flow control is role-neutral. A FlowControlWindow is a sliding window regardless of who created it, and the FlowController distinguishes only connection-level from stream-level — never server from client. The apply_settings_initial_window_size! function responds to a peer's SETTINGS frame the same way whether that frame came from a server or a client.
Client-role code that sends DATA constructs the same DataSender shape as server-role code; the roles diverge only in which side originally advertises the initial window.
Window
PureHTTP2.FlowControlWindow — Type
FlowControlWindow(initial_size::Int = DEFAULT_INITIAL_WINDOW_SIZE)A single HTTP/2 flow-control window (RFC 9113 §5.2). Can represent either a connection-level window or a stream-level window. Thread- safe via an internal ReentrantLock.
Fields
available::Int: Available window sizeinitial_size::Int: Initial window sizepending_updates::Int: Pending WINDOW_UPDATE bytes to sendlock::ReentrantLock: Thread-safe access
Example
julia> using PureHTTP2
julia> window = FlowControlWindow(65535);
julia> consume!(window, 1000)
true
julia> available(window)
64535
julia> release!(window, 1000);
julia> available(window)
65535Window operations
PureHTTP2.consume! — Function
consume!(window::FlowControlWindow, size::Int) -> BoolConsume bytes from the flow control window. Returns true if consumption was successful, false if insufficient window.
PureHTTP2.try_consume! — Function
try_consume!(window::FlowControlWindow, size::Int) -> IntTry to consume up to size bytes from the window. Returns the actual number of bytes consumed.
PureHTTP2.release! — Function
release!(window::FlowControlWindow, size::Int)Release bytes back to the flow control window (for WINDOW_UPDATE).
PureHTTP2.available — Function
available(window::FlowControlWindow) -> IntGet the current available window size.
PureHTTP2.should_send_update — Function
should_send_update(window::FlowControlWindow; threshold_ratio::Float64=0.5) -> BoolCheck if a WINDOW_UPDATE should be sent based on pending updates.
PureHTTP2.get_update_increment — Function
get_update_increment(window::FlowControlWindow) -> IntGet the increment for WINDOW_UPDATE and reset pending updates.
PureHTTP2.update_initial_size! — Function
update_initial_size!(window::FlowControlWindow, new_initial_size::Int)Update the initial window size (from SETTINGS frame). Adjusts the current available window proportionally.
Multi-stream controller
PureHTTP2.FlowController — Type
FlowControllerManages flow control for an HTTP/2 connection.
Fields
connection_window::FlowControlWindow: Connection-level windowstream_windows::Dict{UInt32, FlowControlWindow}: Per-stream windowsinitial_stream_window::Int: Initial window size for new streamslock::ReentrantLock: Thread-safe access to stream windows dict
Controller operations
PureHTTP2.create_stream_window! — Function
create_stream_window!(controller::FlowController, stream_id::UInt32) -> FlowControlWindowCreate a flow control window for a new stream.
PureHTTP2.get_stream_window — Function
get_stream_window(controller::FlowController, stream_id::UInt32) -> Union{FlowControlWindow, Nothing}Get the flow control window for a stream.
PureHTTP2.remove_stream_window! — Function
remove_stream_window!(controller::FlowController, stream_id::UInt32)Remove the flow control window for a closed stream.
PureHTTP2.consume_send! — Function
consume_send!(controller::FlowController, stream_id::UInt32, size::Int) -> BoolConsume bytes from both connection and stream windows for sending.
PureHTTP2.max_sendable — Function
max_sendable(controller::FlowController, stream_id::UInt32) -> IntGet the maximum sendable bytes considering both connection and stream windows.
PureHTTP2.apply_window_update! — Function
apply_window_update!(controller::FlowController, stream_id::UInt32, increment::Int)Apply a received WINDOW_UPDATE to the appropriate window. Stream ID 0 updates the connection window.
PureHTTP2.apply_settings_initial_window_size! — Function
apply_settings_initial_window_size!(controller::FlowController, new_size::Int)Apply a new initial window size from SETTINGS to all existing streams.
PureHTTP2.generate_window_updates — Function
generate_window_updates(controller::FlowController;
threshold_ratio::Float64=0.5) -> Vector{Frame}Generate WINDOW_UPDATE frames for windows that need updating.
High-level senders and receivers
PureHTTP2.DataSender — Type
DataSenderManages sending data with flow control and frame size limits.
Fields
controller::FlowController: Flow controllermax_frame_size::Int: Maximum frame payload size
PureHTTP2.send_data_frames — Function
send_data_frames(sender::DataSender, stream_id::UInt32, data::Vector{UInt8};
end_stream::Bool=false) -> Vector{Frame}Split data into frames respecting flow control and frame size limits. Returns empty vector if no data can be sent due to flow control.
PureHTTP2.DataReceiver — Type
DataReceiverManages receiving data with flow control.
Fields
controller::FlowController: Flow controllermax_frame_size::Int: Maximum allowed frame payload size