Skip to main content

Module buffer_source

Module buffer_source 

Source
Expand description

Where the mux core gets memory, and the one way it is allowed to fail.

The core does not allocate for itself and does not name crate::pool::Pool. Every buffer it needs — a connection’s stream-0 landing zone, a stream’s request/response pair, the HPACK scratch — comes from a caller-supplied BufferSource, which the caller implements and which may refuse. That is the whole contract, and both halves matter:

  • Caller-supplied is what lets something other than the real pool stand behind it. A deterministic simulator that wants to drive the core into memory pressure has somewhere to stand, instead of having to arrange the pressure through a global allocator it does not control.
  • May refuse is what keeps the existing behaviour expressible. Refusal is not an error condition here. A source that answers None mid-request is reporting a transient shortage, and the caller’s obligation is to degrade the smallest unit it can: one stream is refused with RST_STREAM(REFUSED_STREAM) and the connection carries on, because the streams already running will hand their buffers back. Escalating a shortage to a connection error would convert it into the loss of every in-flight request that would have survived it.

Neither half is new behaviour. Both checkout sites were already Option-fallible with a REFUSED_STREAM-shaped fallback; what was missing was a name for the thing being called, so the core reached for a concrete Weak<RefCell<Pool>> instead. This module supplies the name and PoolBufferSource supplies the one implementation the proxy itself uses, which does exactly what the direct reach did.

§What is under the contract, and what is not

Under it: the connection’s own zero buffer, a stream’s request/response buffer pair, and the HPACK codec pair together with the three reusable scratch buffers beside them (see HpackState, hpack_state.rs).

Not under it, deliberately:

  • Growth of the HPACK codec’s own buffers. The dynamic tables of the crate::protocol::mux::hpack pair and the decoder’s Huffman scratch buffer start empty and grow to a high-water mark bounded by the RFC 7541 §4.2 table-size settings and the longest decoded string. They are brought under the contract at acquisition — the pair is built inside a fallible HpackState::new — and their growth after acquisition reaches the global allocator, like a scratch buffer’s below.
  • Growth of an already-acquired scratch buffer. scratch hands over an empty Vec that the core then grows and reclaims on its own schedule. Pre-sizing one and refusing to grow it is a behaviour change — it needs an answer for what a header block larger than the reservation does — and is not made here.
  • H2Scheduler’s pass-order buffer (h2_scheduler.rs). It holds stream ids rather than octets, and it is already bounded by the concurrent-stream admission gate that decides how many ids can exist.

Structs§

PoolBufferSource
The BufferSource the proxy itself runs on: the worker’s shared Pool, reached through the same weak handle the core used to hold directly.

Traits§

BufferSource
The caller-supplied origin of every buffer the mux core uses.