# Shutdown- und Cleanup-Verbesserungen ## Übersicht Die Anwendung hatte Probleme beim ordnungsgemäßen Herunterfahren und Cleanup, die zu hängenden Prozessen und inkonsistenten Zuständen führten. Diese Dokumentation beschreibt die implementierten Verbesserungen. ## Identifizierte Probleme ### Vorherige Probleme 1. **Mehrfache Signal-Handler**: Verschiedene Module registrierten eigene Signal-Handler, die sich gegenseitig interferiert haben 2. **Fehlende Koordination**: Queue Manager, Scheduler und Datenbank-Cleanup wurden unkoordiniert beendet 3. **Keine Timeouts**: Cleanup-Operationen konnten unbegrenzt lange dauern 4. **Scheduler-Shutdown-Probleme**: Der Scheduler wurde nicht robust genug gestoppt 5. **Komplexe Datenbank-Operationen**: Riskante WAL-Mode-Switches während des Shutdowns ### Symptome in den Logs ``` 🛑 Signal 2 empfangen - fahre System herunter... ⚠️ Thread konnte nicht ordnungsgemäß beendet werden ❌ Fehler beim Stoppen des Schedulers 🔄 Führe robustes Datenbank-Cleanup durch... ``` ## Implementierte Lösung: Zentraler Shutdown-Manager ### Neue Architektur #### 1. Zentraler Shutdown-Manager (`utils/shutdown_manager.py`) ```python class ShutdownManager: """ Koordiniert alle Cleanup-Operationen mit Timeouts und Prioritäten """ ``` **Hauptfunktionen:** - **Koordinierte Beendigung**: Alle Komponenten werden in der richtigen Reihenfolge gestoppt - **Prioritäts-basiertes Cleanup**: Cleanup-Funktionen werden nach Priorität (1=hoch, 3=niedrig) ausgeführt - **Timeout-Management**: Jede Operation hat ein konfigurierbares Timeout - **Fehlerbehandlung**: Einzelne Fehler stoppen nicht den gesamten Shutdown-Prozess - **Plattform-spezifisch**: Unterstützt Windows und Unix/Linux Signal-Handling #### 2. Komponenten-Registrierung ```python # Queue Manager registrieren shutdown_manager.register_queue_manager(queue_module) # Scheduler registrieren shutdown_manager.register_scheduler(scheduler, SCHEDULER_ENABLED) # Datenbank-Cleanup registrieren shutdown_manager.register_database_cleanup() # Windows Thread Manager registrieren shutdown_manager.register_windows_thread_manager() ``` #### 3. Prioritäten-System - **Priorität 1 (Hoch)**: Queue Manager, Scheduler - werden zuerst gestoppt - **Priorität 2 (Mittel)**: Windows Thread Manager - wird in der Mitte gestoppt - **Priorität 3 (Niedrig)**: Datenbank-Cleanup - wird am Ende ausgeführt ### Verbesserungen im Detail #### Queue Manager (`utils/queue_manager.py`) **Vorher:** - Registrierte eigene Signal-Handler, die interferierten - Feste 10-Sekunden-Timeouts ohne Flexibilität - Thread-Join ohne Fallback-Strategien **Nachher:** ```python def __init__(self, register_signal_handlers: bool = True): # Signal-Handler nur wenn explizit gewünscht if register_signal_handlers and os.name == 'nt': self._register_signal_handlers() ``` **Verbesserungen:** - Optionale Signal-Handler-Registrierung - Prüfung auf zentralen Shutdown-Manager - Reduzierte Timeouts (5 Sekunden) - Daemon-Thread-Fallback für automatische Beendigung - Verbesserte Fehlerbehandlung #### Scheduler-Integration **Vorher:** ```python scheduler.stop() # Einfache Stop-Methode ``` **Nachher:** ```python def stop_scheduler(): if hasattr(scheduler, 'shutdown'): scheduler.shutdown(wait=True) # Robustere Methode elif hasattr(scheduler, 'stop'): scheduler.stop() ``` #### Datenbank-Cleanup **Vorher:** - Riskante WAL-Mode-Switches während Shutdown - Komplexe Operationen ohne Timeout **Nachher:** ```python def safe_database_cleanup(): # Kein riskantes Mode-Switching beim Shutdown result = safe_database_cleanup(force_mode_switch=False) # Fallback auf einfaches WAL-Checkpoint result = conn.execute(text("PRAGMA wal_checkpoint(PASSIVE)")) ``` ### Konfiguration und Verwendung #### Startup-Konfiguration in `app.py` ```python # Initialisiere zentralen Shutdown-Manager from utils.shutdown_manager import get_shutdown_manager shutdown_manager = get_shutdown_manager(timeout=45) # Registriere alle Komponenten shutdown_manager.register_queue_manager(queue_module) shutdown_manager.register_scheduler(scheduler, SCHEDULER_ENABLED) shutdown_manager.register_database_cleanup() shutdown_manager.register_windows_thread_manager() ``` #### Fallback-Mechanismus Falls der Shutdown-Manager nicht verfügbar ist, wird ein Fallback-Signal-Handler verwendet: ```python except ImportError as e: # Fallback auf vereinfachte Signal-Handler def fallback_signal_handler(sig, frame): stop_queue_manager() if scheduler: scheduler.shutdown(wait=True) sys.exit(0) ``` ### Timeout-Konfiguration | Komponente | Timeout | Begründung | |------------|---------|------------| | Queue Manager | 15s | Zeit für Thread-Beendigung und Cleanup | | Scheduler | 10s | Zeit für laufende Jobs zu beenden | | Datenbank-Cleanup | 20s | Zeit für WAL-Checkpoint und Optimierung | | Windows Thread Manager | 15s | Zeit für alle verwalteten Threads | | **Gesamt** | **45s** | Maximum für komplettes Shutdown | ### Signal-Handler-Koordination #### Vorher (Problematisch) ``` app.py -> SIGINT, SIGTERM, SIGBREAK queue_manager.py -> SIGINT, SIGTERM windows_fixes.py -> SIGINT, SIGTERM, SIGBREAK ``` **Problem:** Mehrfache Handler interferieren, inkonsistente Cleanup-Reihenfolge #### Nachher (Koordiniert) ``` shutdown_manager.py -> SIGINT, SIGTERM, SIGBREAK (zentral) queue_manager.py -> Keine Handler (oder optional als Fallback) windows_fixes.py -> Registriert beim Shutdown-Manager ``` ### Monitoring und Debugging #### Detaillierte Logs ``` 🔧 Shutdown-Manager initialisiert ✅ Queue Manager beim Shutdown-Manager registriert 🔄 Starte koordiniertes System-Shutdown... 🔄 Stoppe 1 registrierte Komponenten... 🧹 Führe 4 Cleanup-Funktionen aus... ✅ Koordiniertes Shutdown abgeschlossen in 3.2s 🏁 System wird beendet... ``` #### Timeout-Überwachung ``` ✅ Queue Manager abgeschlossen in 2.1s ⏱️ Datenbank Cleanup Timeout nach 20.0s ❌ Fehler bei Cleanup 'Windows Thread Manager': Connection refused ``` ### Fehlerbehandlung #### Robuste Cleanup-Ausführung - **Einzelfehler stoppen nicht das gesamte Shutdown** - **Timeouts verhindern hängende Operationen** - **Fallback-Strategien für kritische Komponenten** - **Detaillierte Fehler-Logs für Debugging** #### Graceful Degradation ```python try: # Versuche optimalen Cleanup safe_database_cleanup() except Exception: # Fallback auf minimalen Cleanup basic_wal_checkpoint() ``` ## Testen der Verbesserungen ### Test-Szenarien 1. **Normales Shutdown**: `Ctrl+C` oder `SIGTERM` 2. **Forciertes Shutdown**: Mehrfache `Ctrl+C` 3. **Timeout-Verhalten**: Simuliere hängende Komponenten 4. **Komponenten-Ausfälle**: Simuliere Fehler in einzelnen Cleanup-Funktionen ### Erwartete Verbesserungen - **Reduzierte Shutdown-Zeit**: Von >30s auf <10s in normalen Fällen - **Konsistente Logs**: Klare Shutdown-Sequenz sichtbar - **Keine hängenden Prozesse**: Alle Threads werden ordnungsgemäß beendet - **Robuste Datenbank**: Keine WAL-Korruption oder Lock-Probleme ## Wartung und Erweiterung ### Neue Komponenten hinzufügen ```python # Für Komponenten mit stop()-Methode shutdown_manager.register_component("Meine Komponente", component, "stop") # Für Cleanup-Funktionen shutdown_manager.register_cleanup_function( func=my_cleanup_function, name="Meine Cleanup-Funktion", priority=2, timeout=15 ) ``` ### Troubleshooting #### Häufige Probleme 1. **Import-Fehler**: Shutdown-Manager nicht gefunden -> Fallback wird verwendet 2. **Timeout-Überschreitungen**: Komponente reagiert nicht -> Wird übersprungen 3. **Signal-Handler-Konflikte**: Alte Handler noch registriert -> Deregistrierung nötig #### Debug-Logs aktivieren ```python shutdown_logger.setLevel(logging.DEBUG) ``` ### Zukünftige Verbesserungen - **Health-Checks**: Überwachung der Komponenten-Zustände - **Konfigurierbares Verhalten**: Externe Konfiguration für Timeouts und Prioritäten - **Metrics**: Sammlung von Shutdown-Performance-Daten - **Web-Interface**: Admin-Interface für Shutdown-Management ## Fazit Die Shutdown-Verbesserungen lösen die ursprünglichen Probleme durch: - **Zentrale Koordination** aller Cleanup-Operationen - **Timeout-basierte** Fehlerbehandlung - **Prioritäts-gesteuerte** Ausführungsreihenfolge - **Robuste Fallback-Mechanismen** Das Ergebnis ist ein zuverlässiges, schnelles und debugbares Shutdown-Verhalten.