dashboard: Fix dashboard shutdown/restart 22051/head
authorBoris Ranto <branto@redhat.com>
Thu, 17 May 2018 09:02:29 +0000 (11:02 +0200)
committerBoris Ranto <branto@redhat.com>
Thu, 17 May 2018 09:02:32 +0000 (11:02 +0200)
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 <branto@redhat.com>
src/pybind/mgr/dashboard/module.py

index 8f4a542e06223e6c69654f58eb84f50c788fd61a..9bcdca97a4ddb95a8f14f3e587bba446c0caf22a 100644 (file)
@@ -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...")