removed memory allocations from tryDial. This should improve performance for non-keepalive connections

This commit is contained in:
Aliaksandr Valialkin
2016-05-16 17:17:18 +03:00
parent ecba84a7fe
commit f36b47782a
3 changed files with 56 additions and 36 deletions
+5 -30
View File
@@ -664,16 +664,7 @@ func clientGetURLDeadlineFreeConn(dst []byte, url string, deadline time.Time, c
}
}()
var tc *time.Timer
tcv := timerPool.Get()
if tcv == nil {
tc = time.NewTimer(timeout)
tcv = tc
} else {
tc = tcv.(*time.Timer)
initTimer(tc, timeout)
}
tc := acquireTimer(timeout)
select {
case resp := <-ch:
ReleaseRequest(req)
@@ -685,9 +676,7 @@ func clientGetURLDeadlineFreeConn(dst []byte, url string, deadline time.Time, c
body = dst
err = ErrTimeout
}
stopTimer(tc)
timerPool.Put(tcv)
releaseTimer(tc)
return statusCode, body, err
}
@@ -916,16 +905,7 @@ func clientDoDeadlineFreeConn(req *Request, resp *Response, deadline time.Time,
ch <- c.Do(reqCopy, respCopy)
}()
var tc *time.Timer
tcv := timerPool.Get()
if tcv == nil {
tc = time.NewTimer(timeout)
tcv = tc
} else {
tc = tcv.(*time.Timer)
initTimer(tc, timeout)
}
tc := acquireTimer(timeout)
var err error
select {
case err = <-ch:
@@ -939,17 +919,12 @@ func clientDoDeadlineFreeConn(req *Request, resp *Response, deadline time.Time,
case <-tc.C:
err = ErrTimeout
}
stopTimer(tc)
timerPool.Put(tcv)
releaseTimer(tc)
return err
}
var (
errorChPool sync.Pool
timerPool sync.Pool
)
var errorChPool sync.Pool
// Do performs the given http request and sets the corresponding response.
//
+33 -6
View File
@@ -205,8 +205,18 @@ func tryDial(network string, addr *net.TCPAddr, deadline time.Time, concurrencyC
select {
case concurrencyCh <- struct{}{}:
case <-time.After(timeout):
return nil, ErrDialTimeout
default:
tc := acquireTimer(timeout)
isTimeout := false
select {
case concurrencyCh <- struct{}{}:
case <-tc.C:
isTimeout = true
}
releaseTimer(tc)
if isTimeout {
return nil, ErrDialTimeout
}
}
timeout = -time.Since(deadline)
@@ -215,7 +225,11 @@ func tryDial(network string, addr *net.TCPAddr, deadline time.Time, concurrencyC
return nil, ErrDialTimeout
}
ch := make(chan dialResult, 1)
chv := dialResultChanPool.Get()
if chv == nil {
chv = make(chan dialResult, 1)
}
ch := chv.(chan dialResult)
go func() {
var dr dialResult
dr.conn, dr.err = net.DialTCP(network, nil, addr)
@@ -223,14 +237,27 @@ func tryDial(network string, addr *net.TCPAddr, deadline time.Time, concurrencyC
<-concurrencyCh
}()
var (
conn net.Conn
err error
)
tc := acquireTimer(timeout)
select {
case dr := <-ch:
return dr.conn, dr.err
case <-time.After(timeout):
return nil, ErrDialTimeout
conn = dr.conn
err = dr.err
dialResultChanPool.Put(ch)
case <-tc.C:
err = ErrDialTimeout
}
releaseTimer(tc)
return conn, err
}
var dialResultChanPool sync.Pool
type dialResult struct {
conn net.Conn
err error
+18
View File
@@ -1,6 +1,7 @@
package fasthttp
import (
"sync"
"time"
)
@@ -24,3 +25,20 @@ func stopTimer(t *time.Timer) {
}
}
}
func acquireTimer(timeout time.Duration) *time.Timer {
v := timerPool.Get()
if v == nil {
return time.NewTimer(timeout)
}
t := v.(*time.Timer)
initTimer(t, timeout)
return t
}
func releaseTimer(t *time.Timer) {
stopTimer(t)
timerPool.Put(t)
}
var timerPool sync.Pool