From 72352d7661b6af40da0cbda42c618a63c63d27c3 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 30 Mar 2016 19:35:46 +0300 Subject: [PATCH] workerpool: limit the number of connections each worker may serve. This should reduce the total amount of memory occupied by worker stacks in the long term --- workerpool.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/workerpool.go b/workerpool.go index 78bc30b..0fb6557 100644 --- a/workerpool.go +++ b/workerpool.go @@ -190,7 +190,6 @@ func (wp *workerPool) release(ch *workerChan) bool { func (wp *workerPool) workerFunc(ch *workerChan) { var c net.Conn - var err error defer func() { if r := recover(); r != nil { @@ -206,10 +205,15 @@ func (wp *workerPool) workerFunc(ch *workerChan) { wp.lock.Unlock() }() + var ( + connsServed uint64 + err error + ) for c = range ch.ch { if c == nil { break } + if err = wp.WorkerFunc(c); err != nil && err != errHijacked { errStr := err.Error() if wp.LogAllErrors || !(strings.Contains(errStr, "broken pipe") || @@ -223,8 +227,21 @@ func (wp *workerPool) workerFunc(ch *workerChan) { } c = nil + // Recycle workers in order to reduce the amount of memory occupied + // by worker stacks, which could grow due to stack-hungry request handlers. + connsServed++ + if connsServed >= maxConnsPerWorker { + break + } + if !wp.release(ch) { break } } } + +// maxConnsPerWorker is the maximum number of connections each worker may serve. +// +// This setting allows recycling worker stacks, which could grow during +// execution of stack-hungry request handlers provided by users. +const maxConnsPerWorker = 100