Three paths obtained a client ref and abandoned it without closing: the content-length rejection in call/3, the invalid-status clause in request/4, and the success branch of response/6. Under Hackney 4 an abandoned ref is a permanent process leak. A conn that finishes or errors without an explicit stop parks in `closed` or `connected` and never terminates: closed/3 only arms its stop timer for pooled conns, `connected` gets no state_timeout when idle_timeout is infinity, and a non-pooled conn monitors hackney_conn_sup rather than its caller, so the owner-DOWN cleanup never fires. Each parked process pins every refc binary it read, which for proxied video is tens of MB. Releasing on every outcome means the gun client must stop releasing in stream_body/1, or the ref would be removed twice. Hackney does reclaim a pooled connection itself for a response that cannot carry a body (204, 304, HEAD), so those refs are marked and left alone; stopping one would evict a connection another request may already hold. The mark is gated on the request actually being pooled, since a direct or proxy-tunnelled conn is never checked in and leaks unless we stop it.
1 line
155 B
Text
1 line
155 B
Text
Release the reverse proxy HTTP client on every outcome, fixing a memory leak where abandoned Hackney connection processes retained the whole response body
|