Own a direct connection by the process that opened it - #951
Merged
Merged
Conversation
A connection opened without a pool was started under hackney_conn_sup and owned by it, so a killed caller left the connection and its socket open until the server closed it. connect_direct, start_conn_with_socket and the h2_open stream now pass owner => self(), so the connection closes when its opener dies. Pooled connections are unchanged.
This was referenced Sep 26, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A connection opened without a pool was started under
hackney_conn_sup, so the supervisor was its owner. When the caller was killed, nothing closed it, and withidle_timeoutatinfinitythe socket stayed open until the server closed it. Found in barrel, where a query worker killed at its deadline left its connection open.The start sites now pass
owner => self(), since they run in the caller:hackney:connect_direct/4:request/5andconnect/*with{pool, false}, streamed request bodies, async responses, plain HTTP proxies, and HTTP/2 and HTTP/3 without a poolhackney:start_conn_with_socket_internal/5: CONNECT and SOCKS5 tunnelshackney_h2_stream:establish/2:h2_open/*, so the connection closes even when the stream process is killed beforeterminate/3With
stream_toset to another process, that process owns the connection. This was already the case (#646) and is now tested. The pool path is unchanged, andset_owner/2,3still moves ownership.hackney_direct_owner_testscovers each entry point: kill the opener, then wait for the conn's'DOWN'and the server-side socket close. No sleeps. 10 of its 12 tests fail on 4.8.1. Thestream_toandset_ownertests pass there too, as expected.unpooled_conn_not_sharednow asserts the uploader is monitored once, as owner.Known limit: an HTTP/1.1 conn waiting for a response is blocked in a passive recv, so it sees its owner's death only when the read returns, at the latest after
recv_timeout.