fix(net_http): instrument connection establishment (DNS/TCP/TLS)
Description
Net::HTTP establishes the connection — DNS resolution, TCP connect, TLS handshake — in #do_start, before any #request runs. Because Labkit::NetHttpPublisher#request begins with return super unless started?, the whole connect phase ran outside any instrumented block. As a result:
- a request that hangs during connection setup (slow DNS, blackholed endpoint, TLS stall) contributed nothing to the
request.external_httpduration or count; and - a connection that failed before any request was sent (e.g.
Net::OpenTimeout) emitted no event at all.
This is especially invisible for the explicit-start pattern Net::HTTP.start(host) { |http| http.request(...) }, where connection setup completes entirely before the first #request.
Fix
Instrument #do_start:
- on success, fold the connection-establishment time into the following request's
duration(counted once per connection), so a slow connect is attributed to the request instead of vanishing; - on failure, emit a standalone
request.external_httpevent carrying the exception and elapsed time, so a hung or blackholed connection is still visible and counted.
This covers both the implicit-start and explicit-start patterns. #do_start is kept private, matching Ruby's private :do_start.
Follow-up
External HTTP trace span duration still needs separate follow-up work because tracing currently times the ActiveSupport notification block rather than payload[:duration]: #74
Testing
Two regression specs added to spec/labkit/net_http_publisher_spec.rb (both fail before the change, pass after): one asserting connection-setup time is included in the measured duration (explicit start), one asserting an event is emitted when connection setup fails before any request. Full net_http_publisher_spec passes (37 examples) and RuboCop is clean.
Related Issues
Surfaced by gitlab-org/gitlab#605416 (closed), which documents the downstream impact (archived CI trace reads via Gitlab::HttpIO hanging in connect, invisible in external_http_duration_s).
Note: the Excon and HTTPClient publishers likely share the same structural gap and are worth a follow-up audit; this MR scopes the fix to Net::HTTP.