1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 17:28:08 +00:00

Detect the app is exiting and avoid reconnecting to computes.

This commit is contained in:
grossmj 2021-04-17 18:33:20 +09:30
parent 6b8ce8219c
commit bad3ef7003
4 changed files with 19 additions and 13 deletions

View File

@ -25,7 +25,7 @@ from fastapi import FastAPI, Request
from starlette.exceptions import HTTPException as StarletteHTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from uvicorn.main import Server as UvicornServer
from gns3server.controller.controller_error import (
ControllerError,
@ -82,6 +82,18 @@ def get_application() -> FastAPI:
app = get_application()
# Monkey Patch uvicorn signal handler to detect the application is shutting down
app.state.exiting = False
unicorn_exit_handler = UvicornServer.handle_exit
def handle_exit(*args, **kwargs):
app.state.exiting = True
unicorn_exit_handler(*args, **kwargs)
UvicornServer.handle_exit = handle_exit
@app.exception_handler(ControllerError)
async def controller_error_handler(request: Request, exc: ControllerError):

View File

@ -21,7 +21,6 @@ import asyncio
import async_timeout
import socket
import json
import uuid
import sys
import io
from operator import itemgetter
@ -295,6 +294,7 @@ class Compute:
"""
:param topology_dump: Filter to keep only properties require for saving on disk
"""
if topology_dump:
return {
"compute_id": self._id,
@ -486,7 +486,8 @@ class Compute:
log.info(f"Connection closed to compute '{self._id}' WebSocket '{ws_url}'")
# Try to reconnect after 1 second if server unavailable only if not during tests (otherwise we create a ressources usage bomb)
if self.id != "local" and not hasattr(sys, "_called_from_test") or not sys._called_from_test:
from gns3server.api.server import app
if not app.state.exiting and not hasattr(sys, "_called_from_test") or not sys._called_from_test:
log.info(f"Reconnecting to to compute '{self._id}' WebSocket '{ws_url}'")
asyncio.get_event_loop().call_later(1, lambda: asyncio.ensure_future(self.connect()))

View File

@ -82,7 +82,7 @@ def create_startup_handler(app: FastAPI) -> Callable:
def create_shutdown_handler(app: FastAPI) -> Callable:
"""
Tasks to be performed when the server is shutdown.
Tasks to be performed when the server is exiting.
"""
async def shutdown_handler() -> None:

View File

@ -38,7 +38,6 @@ from gns3server.version import __version__
from gns3server.config import Config
from gns3server.crash_report import CrashReport
from gns3server.api.server import app
from pydantic import ValidationError
import logging
@ -170,22 +169,16 @@ class Server:
config.Server.certkey = args.certkey
config.Server.enable_ssl = args.ssl
async def reload_server(self):
"""
Reload the server.
"""
await Controller.instance().reload()
def _signal_handling(self):
def signal_handler(signame, *args):
try:
if signame == "SIGHUP":
log.info(f"Server has got signal {signame}, reloading...")
asyncio.ensure_future(self.reload_server())
asyncio.ensure_future(Controller.instance().reload())
else:
log.info(f"Server has got signal {signame}, exiting...")
# send SIGTERM to the server PID so uvicorn can shutdown the process
os.kill(os.getpid(), signal.SIGTERM)
except asyncio.CancelledError:
pass