Nous.HTTP.StreamBackend.Hackney (nous v0.16.0)

View Source

Nous.HTTP.StreamBackend implementation backed by :hackney in [{:async, :once}] mode for strict pull-based backpressure.

The consumer calls :hackney.stream_next/1 to ask for one more chunk; hackney reads it off the socket and delivers it as a single message {:hackney_response, conn, chunk_or_done}. Because the network read only happens when the consumer asks for it, the producer literally cannot outrun the consumer — the mailbox stays bounded at one message no matter how slow the consumer is.

Pick this backend when downstream consumers can block per chunk (LiveView fan-out under load, persistence-on-every-chunk, slow IO). For typical LLM workloads where token-generation rate is the bottleneck, Nous.HTTP.StreamBackend.Req is simpler and equally fast.

Hackney 4 option shape

Hackney 4 documents the pull-based form as [{async, once}] — a tuple. The legacy [:async, :once] two-atom form silently puts hackney into push mode (proplists resolves bare :async as {:async, true}), which forfeits the backpressure guarantee. This module uses the tuple form. See deps/hackney/NEWS.md:255-275.

TLS verification

Passes verify: :verify_peer with system CAs from :public_key.cacerts_get/0 explicitly. Hackney's default is :verify_none, which would silently accept MITM'd connections — do not regress this.

Pool

Uses hackney's :default pool (50 conns, 2s idle keepalive) unless the caller passes :pool. Apps that want isolation can pass pool: :my_pool per call after starting the pool with :hackney_pool.start_pool/2.