Issue #956 resolved

wsgiserver's ThreadPool stop() method can take longer than timeout arg to complete

Anonymous created an issue

Somewhat related to one of the complaints on this ticket 691, shutting down CherryPy can take longer than expected. This can happen if you are using multiple threads to handle requests (server.thread_pool > 1) and a threaded browser (ex: Firefox on OS X) has recently loaded a page. This happens because the HTTP 1.1 keep-alive connections are still open, and the '''worker.join(timeout)''' calls inside '''ThreadPool's''' '''stop()''' are performed sequentially.

So for example if you have specified a shutdown timeout of 5 seconds and there are 10 idle but open keep-alive connections, then it can take up to 50 seconds for the shutdown to complete.

My proposed fix is to decrement the timeout by the elapsed time. Note all the threads are sent a _SHUTDOWNREQUEST at the beginning, so after the shutdown timeout has elapsed one can safely presume the timeout is exhausted and immediately fall into the 'forcibly shut down the socket' case if '''worker.isAlive()''' is still True.

-- Matt Bendiksen

My proposed fix to stop() is to after: {{{

!python

    for worker in self._threads:
        self._queue.put(_SHUTDOWNREQUEST)

}}} add: {{{

!python

    start_time = time.time()

}}}

And change: {{{

!python

                    worker.join(timeout)

}}} to: {{{

!python

                    remaining_timeout = timeout - (time.time() - start_time)
                    if remaining_timeout > 0:
                        worker.join(remaining_timeout)

}}}

Reported by matt_cherrypy@perceptiveautomation.com

Comments (2)

  1. Log in to comment