Projektarbeit-MYP/backend/docs/SHUTDOWN_VERBESSERUNGEN.md

264 lines
8.4 KiB
Markdown

# 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.