summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/http2/client_conn_pool.go
diff options
context:
space:
mode:
authordependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2021-08-05 12:20:04 +0000
committerGitHub <noreply@github.com>2021-08-05 12:20:04 +0000
commiteb2e99101aa8e774009b2f177fb4c4c4be54ed59 (patch)
treed1eced42fef958ccfd5aa13dbaf0455b95ac1863 /vendor/golang.org/x/net/http2/client_conn_pool.go
parent117583c293713f2baa920c4035e820ad59fe6622 (diff)
downloadpodman-eb2e99101aa8e774009b2f177fb4c4c4be54ed59.tar.gz
podman-eb2e99101aa8e774009b2f177fb4c4c4be54ed59.tar.bz2
podman-eb2e99101aa8e774009b2f177fb4c4c4be54ed59.zip
Bump k8s.io/apimachinery from 0.21.3 to 0.22.0
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.21.3 to 0.22.0. - [Release notes](https://github.com/kubernetes/apimachinery/releases) - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.21.3...v0.22.0) --- updated-dependencies: - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Diffstat (limited to 'vendor/golang.org/x/net/http2/client_conn_pool.go')
-rw-r--r--vendor/golang.org/x/net/http2/client_conn_pool.go79
1 files changed, 57 insertions, 22 deletions
diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go
index 3a67636fe..652bc11a0 100644
--- a/vendor/golang.org/x/net/http2/client_conn_pool.go
+++ b/vendor/golang.org/x/net/http2/client_conn_pool.go
@@ -7,7 +7,9 @@
package http2
import (
+ "context"
"crypto/tls"
+ "errors"
"net/http"
"sync"
)
@@ -78,61 +80,69 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
// It gets its own connection.
traceGetConn(req, addr)
const singleUse = true
- cc, err := p.t.dialClientConn(addr, singleUse)
+ cc, err := p.t.dialClientConn(req.Context(), addr, singleUse)
if err != nil {
return nil, err
}
return cc, nil
}
- p.mu.Lock()
- for _, cc := range p.conns[addr] {
- if st := cc.idleState(); st.canTakeNewRequest {
- if p.shouldTraceGetConn(st) {
- traceGetConn(req, addr)
+ for {
+ p.mu.Lock()
+ for _, cc := range p.conns[addr] {
+ if st := cc.idleState(); st.canTakeNewRequest {
+ if p.shouldTraceGetConn(st) {
+ traceGetConn(req, addr)
+ }
+ p.mu.Unlock()
+ return cc, nil
}
+ }
+ if !dialOnMiss {
p.mu.Unlock()
- return cc, nil
+ return nil, ErrNoCachedConn
}
- }
- if !dialOnMiss {
+ traceGetConn(req, addr)
+ call := p.getStartDialLocked(req.Context(), addr)
p.mu.Unlock()
- return nil, ErrNoCachedConn
+ <-call.done
+ if shouldRetryDial(call, req) {
+ continue
+ }
+ return call.res, call.err
}
- traceGetConn(req, addr)
- call := p.getStartDialLocked(addr)
- p.mu.Unlock()
- <-call.done
- return call.res, call.err
}
// dialCall is an in-flight Transport dial call to a host.
type dialCall struct {
- _ incomparable
- p *clientConnPool
+ _ incomparable
+ p *clientConnPool
+ // the context associated with the request
+ // that created this dialCall
+ ctx context.Context
done chan struct{} // closed when done
res *ClientConn // valid after done is closed
err error // valid after done is closed
}
// requires p.mu is held.
-func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
+func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *dialCall {
if call, ok := p.dialing[addr]; ok {
// A dial is already in-flight. Don't start another.
return call
}
- call := &dialCall{p: p, done: make(chan struct{})}
+ call := &dialCall{p: p, done: make(chan struct{}), ctx: ctx}
if p.dialing == nil {
p.dialing = make(map[string]*dialCall)
}
p.dialing[addr] = call
- go call.dial(addr)
+ go call.dial(call.ctx, addr)
return call
}
// run in its own goroutine.
-func (c *dialCall) dial(addr string) {
+func (c *dialCall) dial(ctx context.Context, addr string) {
const singleUse = false // shared conn
- c.res, c.err = c.p.t.dialClientConn(addr, singleUse)
+ c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
close(c.done)
c.p.mu.Lock()
@@ -276,3 +286,28 @@ type noDialClientConnPool struct{ *clientConnPool }
func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
return p.getClientConn(req, addr, noDialOnMiss)
}
+
+// shouldRetryDial reports whether the current request should
+// retry dialing after the call finished unsuccessfully, for example
+// if the dial was canceled because of a context cancellation or
+// deadline expiry.
+func shouldRetryDial(call *dialCall, req *http.Request) bool {
+ if call.err == nil {
+ // No error, no need to retry
+ return false
+ }
+ if call.ctx == req.Context() {
+ // If the call has the same context as the request, the dial
+ // should not be retried, since any cancellation will have come
+ // from this request.
+ return false
+ }
+ if !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {
+ // If the call error is not because of a context cancellation or a deadline expiry,
+ // the dial should not be retried.
+ return false
+ }
+ // Only retry if the error is a context cancellation error or deadline expiry
+ // and the context associated with the call was canceled or expired.
+ return call.ctx.Err() != nil
+}