From a7acd399d1455d23c28421d8f52cb339cb32f91b Mon Sep 17 00:00:00 2001 From: Boris Ranto Date: Thu, 17 May 2018 11:02:29 +0200 Subject: [PATCH] dashboard: Fix dashboard shutdown/restart The dashboard serve method uses block which it should not as it can cause several problems when shutting down (restarting) ceph-mgr. As a result the restart of the ceph-mgr module will block until time-out if the dashboard module is enabled. This fixes the problem by using a simple simple shutdown_event instead of block() and stopping the server afterwards. Signed-off-by: Boris Ranto --- src/pybind/mgr/dashboard/module.py | 36 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 8f4a542e06223..9bcdca97a4ddb 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -243,6 +243,7 @@ class Module(MgrModule, SSLCherryPyConfig): mgr.init(self) self._stopping = threading.Event() + self.shutdown_event = threading.Event() @classmethod def can_run(cls): @@ -287,22 +288,22 @@ class Module(MgrModule, SSLCherryPyConfig): cherrypy.engine.start() NotificationQueue.start_queue() TaskManager.init() - logger.info('Waiting for engine...') - cherrypy.engine.block() + logger.info('Engine started.') + # wait for the shutdown event + self.shutdown_event.wait() + self.shutdown_event.clear() + NotificationQueue.stop() + cherrypy.engine.stop() if 'COVERAGE_ENABLED' in os.environ: _cov.stop() _cov.save() - logger.info('Engine done') + logger.info('Engine stopped') def shutdown(self): super(Module, self).shutdown() - SSLCherryPyConfig.shutdown(self) - - logger.info('Stopping server...') - NotificationQueue.stop() - cherrypy.engine.exit() - logger.info('Stopped server') + logger.info('Stopping engine...') + self.shutdown_event.set() def handle_command(self, cmd): res = handle_option_command(cmd) @@ -351,6 +352,7 @@ class StandbyModule(MgrStandbyModule, SSLCherryPyConfig): def __init__(self, *args, **kwargs): super(StandbyModule, self).__init__(*args, **kwargs) SSLCherryPyConfig.__init__(self) + self.shutdown_event = threading.Event() # We can set the global mgr instance to ourselves even though # we're just a standby, because it's enough for logging. @@ -393,14 +395,16 @@ class StandbyModule(MgrStandbyModule, SSLCherryPyConfig): cherrypy.tree.mount(Root(), "{}/".format(self.url_prefix), {}) self.log.info("Starting engine...") cherrypy.engine.start() - self.log.info("Waiting for engine...") - cherrypy.engine.wait(state=cherrypy.engine.states.STOPPED) - self.log.info("Engine done.") + self.log.info("Engine started...") + # Wait for shutdown event + self.shutdown_event.wait() + self.shutdown_event.clear() + cherrypy.engine.stop() + self.log.info("Engine stopped.") def shutdown(self): SSLCherryPyConfig.shutdown(self) - self.log.info("Stopping server...") - cherrypy.engine.wait(state=cherrypy.engine.states.STARTED) - cherrypy.engine.stop() - self.log.info("Stopped server") + self.log.info("Stopping engine...") + self.shutdown_event.set() + self.log.info("Stopped engine...") -- 2.39.5