"feat: Enhanced Windows compatibility in backend utilities"
This commit is contained in:
@@ -19,14 +19,17 @@ import subprocess
|
|||||||
import json
|
import json
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
# Windows-spezifische Fixes früh importieren
|
# Windows-spezifische Fixes früh importieren (nur einmal)
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
try:
|
try:
|
||||||
from utils.windows_fixes import get_windows_thread_manager, apply_all_windows_fixes
|
from utils.windows_fixes import get_windows_thread_manager
|
||||||
apply_all_windows_fixes()
|
# apply_all_windows_fixes() wird automatisch beim Import ausgeführt
|
||||||
except ImportError:
|
except ImportError as e:
|
||||||
# Fallback falls windows_fixes nicht verfügbar
|
# Fallback falls windows_fixes nicht verfügbar
|
||||||
get_windows_thread_manager = None
|
get_windows_thread_manager = None
|
||||||
|
print(f"⚠️ Windows-Fixes nicht verfügbar: {str(e)}")
|
||||||
|
else:
|
||||||
|
get_windows_thread_manager = None
|
||||||
|
|
||||||
# Lokale Imports
|
# Lokale Imports
|
||||||
from models import init_database, create_initial_admin, User, Printer, Job, Stats, SystemLog, get_db_session, GuestRequest, UserPermission, Notification
|
from models import init_database, create_initial_admin, User, Printer, Job, Stats, SystemLog, get_db_session, GuestRequest, UserPermission, Notification
|
||||||
|
@@ -15,6 +15,10 @@ from utils.logging_config import get_logger
|
|||||||
# Logger für Windows-Fixes
|
# Logger für Windows-Fixes
|
||||||
windows_logger = get_logger("windows_fixes")
|
windows_logger = get_logger("windows_fixes")
|
||||||
|
|
||||||
|
# Globale Flags um doppelte Anwendung zu verhindern
|
||||||
|
_windows_fixes_applied = False
|
||||||
|
_socket_patches_applied = False
|
||||||
|
|
||||||
class WindowsThreadManager:
|
class WindowsThreadManager:
|
||||||
"""
|
"""
|
||||||
Verwaltet Threads und deren ordnungsgemäße Beendigung auf Windows.
|
Verwaltet Threads und deren ordnungsgemäße Beendigung auf Windows.
|
||||||
@@ -118,24 +122,42 @@ def fix_windows_socket_issues():
|
|||||||
Anwendung von Windows-spezifischen Socket-Fixes.
|
Anwendung von Windows-spezifischen Socket-Fixes.
|
||||||
Verhindert Socket-Fehler beim Flask Auto-Reload.
|
Verhindert Socket-Fehler beim Flask Auto-Reload.
|
||||||
"""
|
"""
|
||||||
|
global _socket_patches_applied
|
||||||
|
|
||||||
if os.name != 'nt':
|
if os.name != 'nt':
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if _socket_patches_applied:
|
||||||
|
windows_logger.debug("⏭️ Socket-Patches bereits angewendet")
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Socket-Wiederverwendung aktivieren
|
# Socket-Wiederverwendung aktivieren durch monkey-patching
|
||||||
import socket
|
import socket
|
||||||
socket.socket._bind_orig = socket.socket.bind
|
|
||||||
|
# Speichere die ursprüngliche bind-Methode nur einmal
|
||||||
|
if not hasattr(socket.socket, '_original_bind'):
|
||||||
|
socket.socket._original_bind = socket.socket.bind
|
||||||
|
|
||||||
def patched_bind(self, address):
|
def patched_bind(self, address):
|
||||||
"""Gepatchte bind-Methode mit SO_REUSEADDR."""
|
"""Gepatchte bind-Methode mit SO_REUSEADDR."""
|
||||||
try:
|
try:
|
||||||
|
# SO_REUSEADDR setzen
|
||||||
self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
except:
|
except Exception as e:
|
||||||
pass
|
# Ignoriere Fehler, aber logge sie für Debug-Zwecke
|
||||||
return self._bind_orig(address)
|
windows_logger.debug(f"SO_REUSEADDR konnte nicht gesetzt werden: {str(e)}")
|
||||||
|
|
||||||
socket.socket.bind = patched_bind
|
# Rufe die ursprüngliche bind-Methode auf
|
||||||
windows_logger.debug("✅ Windows Socket-Patches angewendet")
|
return socket.socket._original_bind(self, address)
|
||||||
|
|
||||||
|
# Patch nur anwenden wenn noch nicht geschehen
|
||||||
|
if socket.socket.bind.__name__ != 'patched_bind':
|
||||||
|
socket.socket.bind = patched_bind
|
||||||
|
_socket_patches_applied = True
|
||||||
|
windows_logger.debug("✅ Windows Socket-Patches angewendet")
|
||||||
|
else:
|
||||||
|
windows_logger.debug("⏭️ Socket bereits gepatcht")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
windows_logger.warning(f"⚠️ Socket-Patches konnten nicht angewendet werden: {str(e)}")
|
windows_logger.warning(f"⚠️ Socket-Patches konnten nicht angewendet werden: {str(e)}")
|
||||||
@@ -152,11 +174,6 @@ def setup_windows_environment():
|
|||||||
os.environ['PYTHONIOENCODING'] = 'utf-8'
|
os.environ['PYTHONIOENCODING'] = 'utf-8'
|
||||||
os.environ['PYTHONUTF8'] = '1'
|
os.environ['PYTHONUTF8'] = '1'
|
||||||
|
|
||||||
# Thread-Pool-Größe optimieren
|
|
||||||
if 'WERKZEUG_SERVER_FD' not in os.environ:
|
|
||||||
# Nur im Hauptprozess
|
|
||||||
os.environ['WERKZEUG_RUN_MAIN'] = 'true'
|
|
||||||
|
|
||||||
windows_logger.debug("✅ Windows-Umgebung optimiert")
|
windows_logger.debug("✅ Windows-Umgebung optimiert")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -172,10 +189,16 @@ def apply_all_windows_fixes():
|
|||||||
"""
|
"""
|
||||||
Wendet alle Windows-spezifischen Fixes an.
|
Wendet alle Windows-spezifischen Fixes an.
|
||||||
"""
|
"""
|
||||||
|
global _windows_fixes_applied
|
||||||
|
|
||||||
if os.name != 'nt':
|
if os.name != 'nt':
|
||||||
windows_logger.debug("⏭️ Keine Windows-Fixes nötig (nicht Windows)")
|
windows_logger.debug("⏭️ Keine Windows-Fixes nötig (nicht Windows)")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if _windows_fixes_applied:
|
||||||
|
windows_logger.debug("⏭️ Windows-Fixes bereits angewendet")
|
||||||
|
return
|
||||||
|
|
||||||
windows_logger.info("🔧 Wende Windows-spezifische Fixes an...")
|
windows_logger.info("🔧 Wende Windows-spezifische Fixes an...")
|
||||||
|
|
||||||
setup_windows_environment()
|
setup_windows_environment()
|
||||||
@@ -184,11 +207,12 @@ def apply_all_windows_fixes():
|
|||||||
# Thread-Manager initialisieren
|
# Thread-Manager initialisieren
|
||||||
thread_manager = get_windows_thread_manager()
|
thread_manager = get_windows_thread_manager()
|
||||||
|
|
||||||
# Atexit-Handler registrieren
|
# Atexit-Handler nur einmal registrieren
|
||||||
atexit.register(thread_manager.shutdown_all)
|
atexit.register(thread_manager.shutdown_all)
|
||||||
|
|
||||||
|
_windows_fixes_applied = True
|
||||||
windows_logger.info("✅ Alle Windows-Fixes erfolgreich angewendet")
|
windows_logger.info("✅ Alle Windows-Fixes erfolgreich angewendet")
|
||||||
|
|
||||||
# Automatisch Windows-Fixes beim Import anwenden
|
# Automatisch Windows-Fixes beim Import anwenden (nur einmal)
|
||||||
if os.name == 'nt':
|
if os.name == 'nt' and not _windows_fixes_applied:
|
||||||
apply_all_windows_fixes()
|
apply_all_windows_fixes()
|
Reference in New Issue
Block a user