Skip to content

net/http: HTTP/2 client retains an extra connection when client conn not usable path is reached #59155

@bcmills

Description

@bcmills
#!watchflakes
post <- pkg == "net/http" && test == "TestTransportIdleConnTimeout" && `unexpected number of idle conns`

After CL 477196, TestTransportIdleConnTimeout/h2 occasionally fails with an extra connection (https://build.golang.org/log/3ad51e846979ee007b5a6bcae73ea5f5917d6a85):

--- FAIL: TestTransportIdleConnTimeout (0.06s)
    --- FAIL: TestTransportIdleConnTimeout/h2 (0.05s)
        transport_test.go:5073: req 1: unexpected number of idle conns: ["127.0.0.1:39145" "127.0.0.1:39145"]
FAIL
FAIL	net/http	55.461s

This failure mode seems exclusive to the h2 subtest — the HTTP/1 test does not seem to be affected.

I tried playing with the time.Sleep(timeout / 2) call in the doReq loop, and found that the failures are correlated to the Sleep: a longer sleep produces a higher probability of an extra connection.

I added some debug logging, and found that in a successful run each request makes two GetClientConn calls from (*Transport).roundTrip:

In a failing run, during the second doReq call the ReserveNewRequest path is taken first, and RoundTrip on it fails with http2: client conn not usable. The retry hits the http2ErrNoCachedConn path, and the rest of the request falls through to the secondary path as usual. It appears that something about the extra retry causes an additional connection to be added to the pool.

(attn @neild)

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions