mooraker: refactor stop_server()

Shutdown the websocket and http server before doing final component cleanup.  This prevents clients from making a request after components have been closed.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2021-06-07 11:17:52 -04:00
parent 936d766cae
commit b16110bcd0
1 changed files with 28 additions and 13 deletions

View File

@ -541,18 +541,27 @@ class Server:
async def _stop_server(self, exit_reason: str = "restart") -> None: async def _stop_server(self, exit_reason: str = "restart") -> None:
self.server_running = False self.server_running = False
for method in ["on_exit", "close"]: # Call each component's "on_exit" method
for name, component in self.components.items(): for name, component in self.components.items():
if not hasattr(component, method): if hasattr(component, "on_exit"):
continue func: FlexCallback = getattr(component, "on_exit")
func: FlexCallback = getattr(component, method)
try: try:
ret = func() ret = func()
if ret is not None: if ret is not None:
await ret await ret
except Exception: except Exception:
logging.exception( logging.exception(
f"Error executing '{method}()' for component: {name}") f"Error executing 'on_exit()' for component: {name}")
# Sleep for 100ms to allow connected websockets to write out
# remaining data
await gen.sleep(.1)
try:
await self.moonraker_app.close()
except Exception:
logging.exception("Error Closing App")
# Disconnect from Klippy
try: try:
if self.klippy_connection.is_connected(): if self.klippy_connection.is_connected():
self.klippy_disconnect_evt = Event() self.klippy_disconnect_evt = Event()
@ -562,13 +571,19 @@ class Server:
self.klippy_disconnect_evt = None self.klippy_disconnect_evt = None
except Exception: except Exception:
logging.exception("Klippy Disconnect Error") logging.exception("Klippy Disconnect Error")
# Sleep for 100ms to allow connected websockets
# to write out remaining data # Close all components
await gen.sleep(.1) for name, component in self.components.items():
try: if hasattr(component, "close"):
await self.moonraker_app.close() func = getattr(component, "close")
except Exception: try:
logging.exception("Error Closing App") ret = func()
if ret is not None:
await ret
except Exception:
logging.exception(
f"Error executing 'close()' for component: {name}")
self.exit_reason = exit_reason self.exit_reason = exit_reason
aioloop = asyncio.get_event_loop() aioloop = asyncio.get_event_loop()
aioloop.remove_signal_handler(signal.SIGTERM) aioloop.remove_signal_handler(signal.SIGTERM)