Source File
client_conn_pool.go
Belonging Package
golang.org/x/net/http2
package http2
import (
)
type ClientConnPool interface {
GetClientConn(req *http.Request, addr string) (*ClientConn, error)
MarkDead(*ClientConn)
}
type clientConnPoolIdleCloser interface {
ClientConnPool
closeIdleConnections()
}
var (
_ clientConnPoolIdleCloser = (*clientConnPool)(nil)
_ clientConnPoolIdleCloser = noDialClientConnPool{}
)
type clientConnPool struct {
t *Transport
conns map[string][]*ClientConn // key is host:port
dialing map[string]*dialCall // currently in-flight dials
keys map[*ClientConn][]string
addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
}
func ( *clientConnPool) ( *http.Request, string) (*ClientConn, error) {
return .getClientConn(, , dialOnMiss)
}
const (
dialOnMiss = true
noDialOnMiss = false
)
if , := .t.ConnPool.(noDialClientConnPool); ! {
return true
return !.freshConn
}
func ( *clientConnPool) ( *http.Request, string, bool) (*ClientConn, error) {
traceGetConn(, )
const = true
, := .t.dialClientConn(, )
if != nil {
return nil,
}
return , nil
}
.mu.Lock()
for , := range .conns[] {
if := .idleState(); .canTakeNewRequest {
if .shouldTraceGetConn() {
traceGetConn(, )
}
.mu.Unlock()
return , nil
}
}
if ! {
.mu.Unlock()
return nil, ErrNoCachedConn
}
traceGetConn(, )
:= .getStartDialLocked()
.mu.Unlock()
<-.done
return .res, .err
}
type dialCall struct {
_ incomparable
p *clientConnPool
done chan struct{} // closed when done
res *ClientConn // valid after done is closed
err error // valid after done is closed
}
func ( *clientConnPool) ( string) *dialCall {
func ( *clientConnPool) ( string, *Transport, *tls.Conn) ( bool, error) {
.mu.Lock()
for , := range .conns[] {
if .CanTakeNewRequest() {
.mu.Unlock()
return false, nil
}
}
, := .addConnCalls[]
if ! {
if .addConnCalls == nil {
.addConnCalls = make(map[string]*addConnCall)
}
= &addConnCall{
p: ,
done: make(chan struct{}),
}
.addConnCalls[] =
go .run(, , )
}
.mu.Unlock()
<-.done
if .err != nil {
return false, .err
}
return !, nil
}
type addConnCall struct {
_ incomparable
p *clientConnPool
done chan struct{} // closed when done
err error
}
func ( *addConnCall) ( *Transport, string, *tls.Conn) {
, := .NewClientConn()
:= .p
.mu.Lock()
if != nil {
.err =
} else {
.addConnLocked(, )
}
delete(.addConnCalls, )
.mu.Unlock()
close(.done)
}
func ( *clientConnPool) ( string, *ClientConn) {
for , := range .conns[] {
if == {
return
}
}
if .conns == nil {
.conns = make(map[string][]*ClientConn)
}
if .keys == nil {
.keys = make(map[*ClientConn][]string)
}
.conns[] = append(.conns[], )
.keys[] = append(.keys[], )
}
func ( *clientConnPool) ( *ClientConn) {
.mu.Lock()
defer .mu.Unlock()
for , := range .keys[] {
, := .conns[]
if ! {
continue
}
:= filterOutClientConn(, )
if len() > 0 {
.conns[] =
} else {
delete(.conns, )
}
}
delete(.keys, )
}
func ( *clientConnPool) () {
.mu.Lock()
for , := range .conns {
for , := range {
.closeIfIdle()
}
}
}
func ( []*ClientConn, *ClientConn) []*ClientConn {
:= [:0]
for , := range {
if != {
= append(, )
}
type noDialClientConnPool struct{ *clientConnPool }
func ( noDialClientConnPool) ( *http.Request, string) (*ClientConn, error) {
return .getClientConn(, , noDialOnMiss)
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |