Skip to content

Commit

Permalink
Make shutdown timings configurable.
Browse files Browse the repository at this point in the history
  • Loading branch information
dave-shawley committed Sep 2, 2019
1 parent eab16f5 commit 7991f99
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Release History

`Next Release`_
---------------
- Make shutdown timings configurable.

`2.0.1`_ (5 Mar 2019)
----------------------
Expand Down
17 changes: 11 additions & 6 deletions sprockets/http/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
class _ShutdownHandler:
"""Keeps track of the application state during shutdown."""

def __init__(self, io_loop):
def __init__(self, io_loop, shutdown_limit, wait_timeout):
self.io_loop = io_loop
self.logger = logging.getLogger(self.__class__.__name__)
self.pending_callbacks = 0
self.shutdown_limit = 5
self.shutdown_limit = shutdown_limit
self.wait_timeout = wait_timeout
self.__deadline = None

def add_future(self, future):
Expand Down Expand Up @@ -42,7 +43,7 @@ def on_shutdown_ready(self):
def _maybe_stop(self):
now = self.io_loop.time()
if now < self.__deadline and asyncio.Task.all_tasks():
self.io_loop.add_timeout(now + 1, self._maybe_stop)
self.io_loop.add_timeout(now + self.wait_timeout, self._maybe_stop)
else:
self.io_loop.stop()
self.logger.info('stopped IOLoop')
Expand Down Expand Up @@ -103,20 +104,24 @@ def start(self, io_loop):
for callback in self.on_start_callbacks:
io_loop.spawn_callback(callback, self.tornado_application, io_loop)

def stop(self, io_loop):
def stop(self, io_loop, shutdown_limit=5.0, wait_timeout=1.0):
"""
Asynchronously stop the application.
:param tornado.ioloop.IOLoop io_loop: loop to run until all
callbacks, timeouts, and queued calls are complete
:param float shutdown_limit: maximum number of seconds to wait
before terminating
:param float wait_timeout: number of seconds to wait between checks
for pending callbacks & timers
Call this method to start the application shutdown process.
The IOLoop will be stopped once the application is completely
shut down.
shut down or after `shutdown_limit` seconds.
"""
running_async = False
shutdown = _ShutdownHandler(io_loop)
shutdown = _ShutdownHandler(io_loop, shutdown_limit, wait_timeout)
for callback in self.on_shutdown_callbacks:
try:
maybe_future = callback(self.tornado_application)
Expand Down
5 changes: 4 additions & 1 deletion sprockets/http/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def __init__(self, app, before_run=None, on_start=None, shutdown=None):
app, before_run, on_start, shutdown)
self.logger = logging.getLogger('Runner')
self.server = None
self.shutdown_limit = 5.0
self.wait_timeout = 1.0

def start_server(self, port_number, number_of_procs=0):
"""
Expand Down Expand Up @@ -142,7 +144,8 @@ def _shutdown(self):
self.stop_server()

# Start the application shutdown process
self.application.stop(ioloop.IOLoop.instance())
self.application.stop(ioloop.IOLoop.instance(), self.shutdown_limit,
self.wait_timeout)


class RunCommand(cmd.Command):
Expand Down
1 change: 1 addition & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ def add_timeout(_, callback):
self.io_loop._timeouts = [mock.Mock()]
runner = sprockets.http.runner.Runner(self.application)
runner.shutdown_limit = 0.25
runner.wait_timeout = 0.05
runner.run(8000)
runner._shutdown()
self.io_loop.stop.assert_called_once_with()
Expand Down

0 comments on commit 7991f99

Please sign in to comment.