# Windows Socket-Fehler Fix Dokumentation ## Problem Bei der Entwicklung auf Windows-Systemen tritt ein Socket-Fehler beim Flask Auto-Reload auf: ``` OSError: [WinError 10038] Ein Vorgang bezog sich auf ein Objekt, das kein Socket ist ``` ## Ursache Das Problem entsteht durch: 1. Flask's Auto-Reload-Feature startet den Server neu wenn Dateien geändert werden 2. Der Queue Manager startet einen Daemon-Thread für Drucker-Überwachung 3. Beim Neustart wird der alte Thread nicht ordnungsgemäß beendet 4. Socket-Ressourcen werden nicht korrekt freigegeben 5. Windows reagiert besonders empfindlich auf nicht geschlossene Sockets ## Lösung Implementierung eines mehrstufigen Fixes: ### 1. Verbesserter Queue Manager (`utils/queue_manager.py`) - **Threading.Event**: Verwendung von `threading.Event` statt `time.sleep()` für unterbrechbares Warten - **Non-Daemon Threads**: Threads werden als non-daemon erstellt für bessere Kontrolle - **Signal-Handler**: Windows-spezifische Signal-Handler für SIGINT, SIGTERM, SIGBREAK - **Thread-Locks**: Thread-sichere Operationen mit `threading.Lock()` - **Ordnungsgemäße Beendigung**: Timeout-basierte Thread-Beendigung mit Logging ```python # Verbessertes Shutdown-Handling def stop(self): with self._lock: if self.is_running: self.is_running = False self.shutdown_event.set() if self.monitor_thread and self.monitor_thread.is_alive(): self.monitor_thread.join(timeout=10) ``` ### 2. Windows-spezifische Fixes (`utils/windows_fixes.py`) - **Socket-Patches**: SO_REUSEADDR für Socket-Wiederverwendung - **Thread-Manager**: Zentrale Verwaltung aller Threads - **Signal-Handler**: SIGBREAK-Unterstützung für Windows - **Umgebungs-Optimierung**: UTF-8 Encoding und Thread-Pool-Einstellungen ```python def fix_windows_socket_issues(): # Socket-Wiederverwendung aktivieren socket.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ``` ### 3. Verbesserte App-Startup-Logik (`app.py`) - **Prozess-Erkennung**: Queue Manager nur im Hauptprozess starten - **Signal-Handling**: Windows-kompatible Signal-Handler - **Graceful Shutdown**: Koordinierte Beendigung aller Komponenten - **Auto-Reload-Erkennung**: Spezielle Behandlung für Flask Reloader ```python # Nur im Hauptprozess starten (nicht bei Flask Auto-Reload) if not debug_mode or os.environ.get('WERKZEUG_RUN_MAIN') == 'true': queue_manager = start_queue_manager() ``` ## Technische Details ### Threading-Verbesserungen ```python # Alte Implementierung (problematisch) while self.is_running: self._check_waiting_jobs() time.sleep(self.check_interval) # Nicht unterbrechbar # Neue Implementierung (robust) while self.is_running and not self.shutdown_event.is_set(): self._check_waiting_jobs() if self.shutdown_event.wait(timeout=self.check_interval): break # Sofort beenden bei Shutdown-Signal ``` ### Signal-Handling ```python # Windows-spezifische Signale if os.name == 'nt': signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGBREAK, signal_handler) # Windows-spezifisch ``` ### Socket-Optimierung ```python # Gepatchte bind-Methode für Socket-Wiederverwendung def patched_bind(self, address): try: self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except: pass return self._bind_orig(address) ``` ## Vorteile der Lösung ### 1. Robustheit - Threads werden immer ordnungsgemäß beendet - Socket-Ressourcen werden korrekt freigegeben - Keine hängenden Prozesse bei Auto-Reload ### 2. Windows-Kompatibilität - Spezielle Behandlung für Windows-Eigenarten - SIGBREAK-Signal-Unterstützung - SO_REUSEADDR für Socket-Wiederverwendung ### 3. Entwicklerfreundlichkeit - Auto-Reload funktioniert ohne Fehler - Detailliertes Logging für Debugging - Automatische Cleanup-Prozesse ### 4. Produktions-Tauglichkeit - Graceful Shutdown in Produktionsumgebung - Thread-sichere Operationen - Robuste Fehlerbehandlung ## Konfiguration ### Environment-Variablen ```bash # Für bessere Windows-Kompatibilität PYTHONIOENCODING=utf-8 PYTHONUTF8=1 WERKZEUG_RUN_MAIN=true ``` ### Flask-Konfiguration (Debug-Modus) ```python if os.name == 'nt': # Windows app.run( host="0.0.0.0", port=5000, debug=True, threaded=True, use_reloader=True, reloader_interval=1, passthrough_errors=False ) ``` ## Monitoring ### Log-Ausgaben ``` ✅ Printer Queue Manager erfolgreich gestartet 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden) 🛑 Signal 2 empfangen - fahre System herunter... 🔄 Beende Queue Manager... ✅ Monitor-Thread erfolgreich beendet ``` ### Gesundheitsprüfung ```python def is_healthy(self) -> bool: return (self.is_running and self.monitor_thread is not None and self.monitor_thread.is_alive() and not self.shutdown_event.is_set()) ``` ## Bekannte Probleme und Workarounds ### Problem: Thread bleibt hängen **Lösung**: Timeout-basierte Thread-Beendigung mit Warnung ### Problem: Socket bereits in Verwendung **Lösung**: SO_REUSEADDR aktivieren ### Problem: Auto-Reload startet Queue Manager mehrfach **Lösung**: Prozess-Erkennung über WERKZEUG_RUN_MAIN ## Testing ```bash # Test mit Debug-Modus python app.py --debug # Test mit Produktions-Modus python app.py # Überwachung der Logs tail -f logs/app/app.log | grep "Queue Manager" ``` ## Wartung - Regelmäßige Überprüfung der Thread-Gesundheit - Monitoring der Socket-Verwendung - Log-Analyse für hanging Threads - Performance-Überwachung der Thread-Beendigung ## Fazit Dieser Fix behebt das Windows Socket-Problem vollständig durch: 1. Ordnungsgemäße Thread-Verwaltung 2. Windows-spezifische Socket-Behandlung 3. Robuste Signal-Handler 4. Graceful Shutdown-Mechanismen Das System ist jetzt sowohl für Entwicklung als auch Produktion auf Windows-Systemen stabil einsetzbar.