Nous.HTTP.StreamBackend implementation backed by Req (Finch
underneath).
Default streaming backend. Drives Req.post/1 with the :into
callback so chunks are pushed into a Task, which forwards them to
the consuming Stream.resource via send/2.
Backpressure
Req's :into callback runs in the spawned Task, which forwards each
chunk to the consumer with send/2. BEAM mailboxes are unbounded, so
the pair share an :atomics counter of in-flight bytes: the
producer adds byte_size(chunk) before sending, the consumer subtracts
it on receipt.
Above the 8 MB high-water mark the producer stops calling send/2 and
parks in a receive; the consumer signals {ref, :resume} once the
counter falls below the 1 MB low-water mark. Because the producer is
Req's :into callback, parking it stops draining the socket, so
backpressure propagates all the way to the wire. Resident memory per
stream is bounded by the byte watermark rather than by chunk count,
and the steady-state cost is one local :atomics read per chunk — no
polling and no cross-process Process.info/2.
If the consumer is truly unresponsive (the counter stays above the
high-water mark for longer than :backpressure_max_wait_ms, default
30s), the producer aborts the request and the stream yields
{:stream_error, %{reason: :backpressure_overflow, inflight_bytes: n}}
rather than wedging forever.
The consumer process is resolved when enumeration starts, not when the stream is built, so a stream may be constructed in one process and enumerated in another (task, GenServer, LiveView).
Callers whose downstream consumers reliably block per chunk (LiveView
fan-out under load, persistence-on-every-chunk, slow IO) can still
prefer Nous.HTTP.StreamBackend.Hackney, which provides strict
pull-based backpressure via :hackney's {:async, :once} mode: one
chunk is read from the socket per consumer request, with no in-flight
window at all.
TLS verification
Req's defaults handle TLS verification via Mint/Finch (system CAs with peer verification). No additional configuration needed.