diff --git a/client.go b/client.go index 48e9c7d..1e3adf3 100644 --- a/client.go +++ b/client.go @@ -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 diff --git a/workerpool.go b/workerpool.go index 044ad11..ef6ef18 100644 --- a/workerpool.go +++ b/workerpool.go @@ -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()