Skip to content

Commit 02337b9

Browse files
authored
Merge pull request #193 from SenseUnit/h2_pooling_improvements
HTTP/2 pooling improvements
2 parents b606d5b + 9dded4c commit 02337b9

1 file changed

Lines changed: 17 additions & 44 deletions

File tree

dialer/h2_client_conn_pool.go

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,11 @@ import (
2222
type clientConnPool struct {
2323
t *http2.Transport
2424

25-
mu sync.Mutex // TODO: maybe switch to RWMutex
26-
// TODO: add support for sharing conns based on cert names
27-
// (e.g. share conn for googleapis.com and appspot.com)
28-
conns map[string][]*http2.ClientConn // key is host:port
29-
dialing map[string]*dialCall // currently in-flight dials
30-
keys map[*http2.ClientConn][]string
31-
addConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls
32-
prepare func(context.Context, *http2.ClientConn) (*http2.ClientConn, error)
25+
mu sync.Mutex
26+
conns []*http2.ClientConn
27+
dialing *dialCall // currently in-flight dial
28+
addConnCall *addConnCall // in-flight addConnIfNeeded calls
29+
prepare func(context.Context, *http2.ClientConn) (*http2.ClientConn, error)
3330
}
3431

3532
func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*http2.ClientConn, error) {
@@ -134,7 +131,7 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
134131
}
135132
for {
136133
p.mu.Lock()
137-
for _, cc := range p.conns[addr] {
134+
for _, cc := range p.conns {
138135
if cc.ReserveNewRequest() {
139136
p.mu.Unlock()
140137
return cc, nil
@@ -179,15 +176,12 @@ type dialCall struct {
179176

180177
// requires p.mu is held.
181178
func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *dialCall {
182-
if call, ok := p.dialing[addr]; ok {
179+
if call := p.dialing; call != nil {
183180
// A dial is already in-flight. Don't start another.
184181
return call
185182
}
186183
call := &dialCall{p: p, done: make(chan struct{}), ctx: ctx}
187-
if p.dialing == nil {
188-
p.dialing = make(map[string]*dialCall)
189-
}
190-
p.dialing[addr] = call
184+
p.dialing = call
191185
go call.dial(call.ctx, addr)
192186
return call
193187
}
@@ -197,7 +191,7 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
197191
c.res, c.err = c.p.dialClientConn(ctx, addr)
198192

199193
c.p.mu.Lock()
200-
delete(c.p.dialing, addr)
194+
c.p.dialing = nil
201195
if c.err == nil {
202196
c.p.addConnLocked(addr, c.res)
203197
}
@@ -216,22 +210,20 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
216210
// c is never closed.
217211
func (p *clientConnPool) addConnIfNeeded(key string, t *http2.Transport, c net.Conn) (used bool, err error) {
218212
p.mu.Lock()
219-
for _, cc := range p.conns[key] {
213+
for _, cc := range p.conns {
220214
if cc.CanTakeNewRequest() {
221215
p.mu.Unlock()
222216
return false, nil
223217
}
224218
}
225-
call, dup := p.addConnCalls[key]
219+
call := p.addConnCall
220+
dup := call != nil
226221
if !dup {
227-
if p.addConnCalls == nil {
228-
p.addConnCalls = make(map[string]*addConnCall)
229-
}
230222
call = &addConnCall{
231223
p: p,
232224
done: make(chan struct{}),
233225
}
234-
p.addConnCalls[key] = call
226+
p.addConnCall = call
235227
go call.run(t, key, c)
236228
}
237229
p.mu.Unlock()
@@ -260,44 +252,25 @@ func (c *addConnCall) run(t *http2.Transport, key string, nc net.Conn) {
260252
} else {
261253
p.addConnLocked(key, cc)
262254
}
263-
delete(p.addConnCalls, key)
255+
p.addConnCall = nil
264256
p.mu.Unlock()
265257
close(c.done)
266258
}
267259

268260
// p.mu must be held
269261
func (p *clientConnPool) addConnLocked(key string, cc *http2.ClientConn) {
270-
for _, v := range p.conns[key] {
262+
for _, v := range p.conns {
271263
if v == cc {
272264
return
273265
}
274266
}
275-
if p.conns == nil {
276-
p.conns = make(map[string][]*http2.ClientConn)
277-
}
278-
if p.keys == nil {
279-
p.keys = make(map[*http2.ClientConn][]string)
280-
}
281-
p.conns[key] = append(p.conns[key], cc)
282-
p.keys[cc] = append(p.keys[cc], key)
267+
p.conns = append(p.conns, cc)
283268
}
284269

285270
func (p *clientConnPool) MarkDead(cc *http2.ClientConn) {
286271
p.mu.Lock()
287272
defer p.mu.Unlock()
288-
for _, key := range p.keys[cc] {
289-
vv, ok := p.conns[key]
290-
if !ok {
291-
continue
292-
}
293-
newList := filterOutClientConn(vv, cc)
294-
if len(newList) > 0 {
295-
p.conns[key] = newList
296-
} else {
297-
delete(p.conns, key)
298-
}
299-
}
300-
delete(p.keys, cc)
273+
p.conns = filterOutClientConn(p.conns, cc)
301274
}
302275

303276
func filterOutClientConn(in []*http2.ClientConn, exclude *http2.ClientConn) []*http2.ClientConn {

0 commit comments

Comments
 (0)