mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-26 00:38:10 +00:00
Detect the app is exiting and avoid reconnecting to computes.
This commit is contained in:
parent
6b8ce8219c
commit
bad3ef7003
@ -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):
|
||||
|
@ -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()))
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user