quic_flow (quic v1.10.0)

View Source

Connection-level flow control accounting.

Standalone helper: quic_connection does not use it. The flow control that runs on the wire is inline in quic_connection, which auto-tunes the window from the RTT, keeps per-stream limits, sends the frames and closes the connection on a violation. Read that for the library's behaviour; use this module when you want the accounting on its own.

What it does: - Tracking bytes sent against peer's MAX_DATA limit - Tracking bytes received against our MAX_DATA limit - Telling you when a MAX_DATA update is due, and what value to grant - Detecting when we're blocked by flow control

What it does not do: stream-level accounting, and sending anything. It emits no frames, so you send MAX_DATA and DATA_BLOCKED yourself and you decide what a violation does.

Flow Control Concepts

- MAX_DATA: Maximum total bytes the peer can send - DATA_BLOCKED: Indicates sender is blocked by receiver's limit - Window: The difference between max_data and bytes received

Summary

Functions

Get total bytes we've received.

Get total bytes we've sent.

Check if we can send the specified number of bytes.

Generate a new MAX_DATA value to send. Returns {NewMaxData, UpdatedState}.

Create a new flow control state.

Create a new flow control state with options.

Record that we received data.

Record that we sent data. Returns {ok, NewState} or {blocked, NewState} if we hit the limit.

Process a MAX_DATA frame from peer. Updates our send limit.

Get our current receive limit (our MAX_DATA).

Get available receive window.

Check if we're currently blocked on send flow control.

Get our current send limit (peer's MAX_DATA).

Get available send window.

Check if we should send a MAX_DATA update. True once the granted window is down to its last ?WINDOW_UPDATE_THRESHOLD fraction. That constant is the fraction remaining, not the fraction consumed, so 0.75 fires after 25% of the window has been used.

Types

flow_state/0

-opaque flow_state()

Functions

bytes_received(Flow_state)

-spec bytes_received(flow_state()) -> non_neg_integer().

Get total bytes we've received.

bytes_sent(Flow_state)

-spec bytes_sent(flow_state()) -> non_neg_integer().

Get total bytes we've sent.

can_send(Flow_state, Size)

-spec can_send(flow_state(), non_neg_integer()) -> boolean().

Check if we can send the specified number of bytes.

generate_max_data(Flow_state)

-spec generate_max_data(flow_state()) -> {non_neg_integer(), flow_state()}.

Generate a new MAX_DATA value to send. Returns {NewMaxData, UpdatedState}.

new()

-spec new() -> flow_state().

Create a new flow control state.

new(Opts)

-spec new(map()) -> flow_state().

Create a new flow control state with options.

on_data_received(Flow_state, Size)

-spec on_data_received(flow_state(), non_neg_integer()) ->
                          {ok, flow_state()} | {error, flow_control_error}.

Record that we received data.

on_data_sent(Flow_state, Size)

-spec on_data_sent(flow_state(), non_neg_integer()) -> {ok | blocked, flow_state()}.

Record that we sent data. Returns {ok, NewState} or {blocked, NewState} if we hit the limit.

on_max_data_received(Flow_state, NewMax)

-spec on_max_data_received(flow_state(), non_neg_integer()) -> flow_state().

Process a MAX_DATA frame from peer. Updates our send limit.

recv_limit(Flow_state)

-spec recv_limit(flow_state()) -> non_neg_integer().

Get our current receive limit (our MAX_DATA).

recv_window(Flow_state)

-spec recv_window(flow_state()) -> non_neg_integer().

Get available receive window.

send_blocked(Flow_state)

-spec send_blocked(flow_state()) -> boolean().

Check if we're currently blocked on send flow control.

send_limit(Flow_state)

-spec send_limit(flow_state()) -> non_neg_integer().

Get our current send limit (peer's MAX_DATA).

send_window(Flow_state)

-spec send_window(flow_state()) -> non_neg_integer().

Get available send window.

should_send_max_data(Flow_state)

-spec should_send_max_data(flow_state()) -> boolean().

Check if we should send a MAX_DATA update. True once the granted window is down to its last ?WINDOW_UPDATE_THRESHOLD fraction. That constant is the fraction remaining, not the fraction consumed, so 0.75 fires after 25% of the window has been used.