mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-14 15:56:44 +03:00
Avoid memory allocation when cleaning stale workers and connections
This commit is contained in:
@@ -892,17 +892,20 @@ func (c *HostClient) connsCleaner() {
|
||||
for {
|
||||
t := time.Now()
|
||||
c.connsLock.Lock()
|
||||
for len(c.conns) > 0 && t.Sub(c.conns[0].t) > 10*time.Second {
|
||||
cc := c.conns[0]
|
||||
conns := c.conns
|
||||
for len(conns) > 0 && t.Sub(conns[0].t) > 10*time.Second {
|
||||
cc := conns[0]
|
||||
c.connsCount--
|
||||
cc.c.Close()
|
||||
releaseClientConn(cc)
|
||||
|
||||
// Do not copy(c.conns, c.conns[1:]), since this may be
|
||||
// quite slow for multi-million conns count.
|
||||
// Just move c.conns one position ahead.
|
||||
c.conns[0] = nil
|
||||
c.conns = c.conns[1:]
|
||||
conns = conns[1:]
|
||||
}
|
||||
if len(conns) < len(c.conns) {
|
||||
copy(c.conns, conns)
|
||||
for i := len(conns); i < len(c.conns); i++ {
|
||||
c.conns[i] = nil
|
||||
}
|
||||
c.conns = c.conns[:len(conns)]
|
||||
}
|
||||
if c.connsCount == 0 {
|
||||
mustStop = true
|
||||
|
||||
+15
-13
@@ -79,19 +79,21 @@ func (wp *workerPool) clean() {
|
||||
// Clean least recently used workers if they didn't serve connections
|
||||
// for more than one second.
|
||||
wp.lock.Lock()
|
||||
chans := wp.ready
|
||||
for len(chans) > 1 && time.Since(chans[0].t) > time.Second {
|
||||
ready := wp.ready
|
||||
for len(ready) > 1 && time.Since(ready[0].t) > 10*time.Second {
|
||||
// notify the worker to stop.
|
||||
chans[0].ch <- nil
|
||||
ready[0].ch <- nil
|
||||
|
||||
// do not do copy(chans, chans[1:]), since this may be quite slow
|
||||
// for multi-million concurrent connections. Just move chans
|
||||
// pointer one position ahead.
|
||||
chans[0] = nil
|
||||
chans = chans[1:]
|
||||
ready = ready[1:]
|
||||
wp.workersCount--
|
||||
}
|
||||
wp.ready = chans
|
||||
if len(ready) < len(wp.ready) {
|
||||
copy(wp.ready, ready)
|
||||
for i := len(ready); i < len(wp.ready); i++ {
|
||||
wp.ready[i] = nil
|
||||
}
|
||||
wp.ready = wp.ready[:len(ready)]
|
||||
}
|
||||
wp.lock.Unlock()
|
||||
}
|
||||
|
||||
@@ -123,16 +125,16 @@ func (wp *workerPool) getCh() *workerChan {
|
||||
createWorker := false
|
||||
|
||||
wp.lock.Lock()
|
||||
chans := wp.ready
|
||||
n := len(chans) - 1
|
||||
ready := wp.ready
|
||||
n := len(ready) - 1
|
||||
if n < 0 {
|
||||
if wp.workersCount < wp.MaxWorkersCount {
|
||||
createWorker = true
|
||||
wp.workersCount++
|
||||
}
|
||||
} else {
|
||||
ch = chans[n]
|
||||
wp.ready = chans[:n]
|
||||
ch = ready[n]
|
||||
wp.ready = ready[:n]
|
||||
}
|
||||
wp.lock.Unlock()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user