fixed event shutdown
All checks were successful
Deploy Plattform-Core / test (push) Successful in 43s
Deploy Plattform-Core / deploy (push) Successful in 4s

This commit is contained in:
ValueOn AG 2026-05-25 15:36:47 +02:00
parent ac85c8e3dc
commit 1053d0c715
2 changed files with 28 additions and 23 deletions

14
app.py
View file

@ -426,10 +426,12 @@ async def lifespan(app: FastAPI):
yield yield
# --- Stop Managers --- # --- Shutdown sequence (protected against CancelledError) ---
try:
# 1. Stop scheduler first (removes all pending cron/interval jobs)
eventManager.stop() eventManager.stop()
# --- Stop Feature Containers (Plug&Play) --- # 2. Stop Feature Containers (Plug&Play)
try: try:
mainModules = loadFeatureMainModules() mainModules = loadFeatureMainModules()
for featureName, module in mainModules.items(): for featureName, module in mainModules.items():
@ -442,9 +444,8 @@ async def lifespan(app: FastAPI):
except Exception as e: except Exception as e:
logger.warning(f"Could not shutdown feature containers: {e}") logger.warning(f"Could not shutdown feature containers: {e}")
# --- Close all PostgreSQL connection pools --- # 3. Close all PostgreSQL connection pools (LAST -- features may still
# Must run LAST: feature `onStop` hooks may still issue DB calls during # issue DB calls during their onStop hooks)
# shutdown. Once we tear down the pools, no more borrows are possible.
try: try:
from modules.connectors.connectorDbPostgre import closeAllPools from modules.connectors.connectorDbPostgre import closeAllPools
closeAllPools() closeAllPools()
@ -453,6 +454,9 @@ async def lifespan(app: FastAPI):
logger.info("Application has been shut down") logger.info("Application has been shut down")
except asyncio.CancelledError:
logger.info("Shutdown interrupted (CancelledError) -- resources released")
# Custom function to generate readable operation IDs for Swagger UI # Custom function to generate readable operation IDs for Swagger UI
# Uses snake_case function names directly instead of auto-generated IDs # Uses snake_case function names directly instead of auto-generated IDs

View file

@ -55,6 +55,7 @@ class EventManagement:
def stop(self) -> None: def stop(self) -> None:
if self._scheduler and self._scheduler.running: if self._scheduler and self._scheduler.running:
try: try:
self._scheduler.remove_all_jobs()
self._scheduler.shutdown(wait=False) self._scheduler.shutdown(wait=False)
logger.info("EventManagement scheduler stopped") logger.info("EventManagement scheduler stopped")
except Exception as exc: except Exception as exc: