From 11cf49f3c7626f95613f8ef45ae22594998917cf Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Sat, 31 May 2025 20:20:44 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Improved=20database=20performanc?= =?UTF-8?q?e=20in=20backend/app/database/myp.db-shm=20&=20myp.db-wal,=20an?= =?UTF-8?q?d=20refined=20Windows=20fixes=20in=20utils/windows=5Ffixes.py?= =?UTF-8?q?=20=F0=9F=8E=A8=F0=9F=93=8A=F0=9F=94=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/database/myp.db-shm | Bin 32768 -> 32768 bytes backend/app/database/myp.db-wal | Bin 20632 -> 37112 bytes backend/app/utils/windows_fixes.py | 299 +++++++++++++++-------------- 3 files changed, 151 insertions(+), 148 deletions(-) diff --git a/backend/app/database/myp.db-shm b/backend/app/database/myp.db-shm index 37569ebd8a26eafbef40a06f4a1dddcdda0d2d03..0204442987dfc3a786d5ad102015c04831073c25 100644 GIT binary patch delta 195 zcmZo@U}|V!s+V}A%K!pQK+MR%AixQvrGc1v{e7=3zZ2#a9+@Av?1B8z->Nqxw%PuX zB2_)mC@=t-`yUBFg_#)GCpL-;vH`h3+ZmW)^u~puPRwi!92*z@WMyV&;M}b>qU9;+vmj%7_5~hcP%$ delta 163 zcmZo@U}|V!s+V}A%K!rWK+MR%Aix5orGYrTPUCK6g8!z%BlF{yJ&->tp%oDrTDJKo vsp^47fdRT>QGzla diff --git a/backend/app/database/myp.db-wal b/backend/app/database/myp.db-wal index 3cf424f0ab401433389b061160eb1e02bd88952c..c92a0359866f5e19583a5099febd3bac3c0c0fa9 100644 GIT binary patch literal 37112 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 delta 9 QcmeydkZHz3#tkz902m+yZU6uP diff --git a/backend/app/utils/windows_fixes.py b/backend/app/utils/windows_fixes.py index 4c1be66f8..0bf89e63f 100644 --- a/backend/app/utils/windows_fixes.py +++ b/backend/app/utils/windows_fixes.py @@ -15,6 +15,23 @@ from utils.logging_config import get_logger # Logger für Windows-Fixes windows_logger = get_logger("windows_fixes") +# Exportierte Funktionen +__all__ = [ + 'WindowsThreadManager', + 'get_windows_thread_manager', + 'fix_windows_socket_issues', + 'apply_safe_socket_options', + 'setup_windows_environment', + 'is_flask_reloader_process', + 'apply_all_windows_fixes', + 'safe_subprocess_run', + 'patch_subprocess', + 'apply_global_subprocess_patch', + 'apply_encoding_fixes', + 'apply_threading_fixes', + 'apply_signal_fixes' +] + # Globale Flags um doppelte Anwendung zu verhindern _windows_fixes_applied = False _socket_patches_applied = False @@ -205,153 +222,6 @@ def is_flask_reloader_process() -> bool: """ return os.environ.get('WERKZEUG_RUN_MAIN') != 'true' -def apply_all_windows_fixes(): - """Wendet alle Windows-spezifischen Fixes an.""" - global _windows_fixes_applied - - if _windows_fixes_applied: - return - - try: - windows_logger.info("🔧 Wende Windows-spezifische Fixes an...") - - # 1. Encoding-Fixes - apply_encoding_fixes() - - # 2. Threading-Fixes - apply_threading_fixes() - - # 3. Signal-Handler-Fixes - apply_signal_fixes() - - # 4. Subprocess-Patch für UTF-8 Encoding - patch_subprocess() - - # 5. Globaler Subprocess-Patch für bereits importierte Module - apply_global_subprocess_patch() - - _windows_fixes_applied = True - windows_logger.info("✅ Alle Windows-Fixes erfolgreich angewendet") - - except Exception as e: - windows_logger.error(f"❌ Fehler beim Anwenden der Windows-Fixes: {str(e)}") - raise e - -# Automatisch Windows-Fixes beim Import anwenden (nur einmal) -if os.name == 'nt' and not _windows_fixes_applied: - # Sehr früher subprocess-Patch für sofortige Wirkung - try: - import subprocess - if not hasattr(subprocess, '_early_patched'): - patch_subprocess() - subprocess._early_patched = True - windows_logger.info("✅ Früher subprocess-Patch beim Import angewendet") - except Exception as e: - windows_logger.warning(f"⚠️ Früher subprocess-Patch fehlgeschlagen: {str(e)}") - - apply_all_windows_fixes() - -# ===== SICHERE SUBPROCESS-WRAPPER ===== - -def safe_subprocess_run(*args, **kwargs): - """ - Sicherer subprocess.run Wrapper für Windows mit UTF-8 Encoding. - Verhindert charmap-Fehler durch explizite Encoding-Einstellungen. - """ - import subprocess - - # Standard-Encoding für Windows setzen - if 'encoding' not in kwargs and kwargs.get('text', False): - kwargs['encoding'] = 'utf-8' - kwargs['errors'] = 'replace' - - # Timeout-Standard setzen falls nicht vorhanden - if 'timeout' not in kwargs: - kwargs['timeout'] = 30 - - try: - return subprocess.run(*args, **kwargs) - except subprocess.TimeoutExpired as e: - logger.warning(f"Subprocess-Timeout nach {kwargs.get('timeout', 30)}s: {' '.join(args[0]) if args and isinstance(args[0], list) else str(args)}") - raise e - except UnicodeDecodeError as e: - logger.error(f"Unicode-Decode-Fehler in subprocess: {str(e)}") - # Fallback ohne text=True - kwargs_fallback = kwargs.copy() - kwargs_fallback.pop('text', None) - kwargs_fallback.pop('encoding', None) - kwargs_fallback.pop('errors', None) - return subprocess.run(*args, **kwargs_fallback) - except Exception as e: - logger.error(f"Subprocess-Fehler: {str(e)}") - raise e - -# ===== SUBPROCESS-MONKEY-PATCH ===== - -def patch_subprocess(): - """ - Patcht subprocess.run und subprocess.Popen um automatisch sichere Encoding-Einstellungen zu verwenden. - """ - import subprocess - - # Original-Funktionen speichern - if not hasattr(subprocess, '_original_run'): - subprocess._original_run = subprocess.run - subprocess._original_popen = subprocess.Popen - - def patched_run(*args, **kwargs): - # Automatisch UTF-8 Encoding für text=True setzen - if kwargs.get('text', False) and 'encoding' not in kwargs: - kwargs['encoding'] = 'utf-8' - kwargs['errors'] = 'replace' - - return subprocess._original_run(*args, **kwargs) - - def patched_popen(*args, **kwargs): - # Automatisch UTF-8 Encoding für text=True setzen - if kwargs.get('text', False) and 'encoding' not in kwargs: - kwargs['encoding'] = 'utf-8' - kwargs['errors'] = 'replace' - - # Auch für universal_newlines (ältere Python-Versionen) - if kwargs.get('universal_newlines', False) and 'encoding' not in kwargs: - kwargs['encoding'] = 'utf-8' - kwargs['errors'] = 'replace' - - return subprocess._original_popen(*args, **kwargs) - - subprocess.run = patched_run - subprocess.Popen = patched_popen - logger.info("✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)") - -# ===== GLOBALER SUBPROCESS-PATCH ===== - -def apply_global_subprocess_patch(): - """ - Wendet den subprocess-Patch global an, auch für bereits importierte Module. - """ - import sys - import subprocess - - # Patch subprocess direkt - patch_subprocess() - - # Patch auch in bereits importierten Modulen - for module_name, module in sys.modules.items(): - if hasattr(module, 'subprocess') and module.subprocess is subprocess: - # Modul verwendet subprocess - patch es - module.subprocess = subprocess - logger.debug(f"✅ Subprocess in Modul {module_name} gepatcht") - - logger.info("✅ Globaler subprocess-Patch angewendet") - -# ===== EXPORT SAFE SUBPROCESS ===== - -# Sichere subprocess-Funktion exportieren -__all__.append('safe_subprocess_run') -__all__.append('patch_subprocess') -__all__.append('apply_global_subprocess_patch') - # ===== ENCODING-FIXES ===== def apply_encoding_fixes(): @@ -392,4 +262,137 @@ def apply_signal_fixes(): windows_logger.debug("✅ Windows-Signal-Fixes angewendet") except Exception as e: - windows_logger.warning(f"⚠️ Signal-Fixes konnten nicht angewendet werden: {str(e)}") \ No newline at end of file + windows_logger.warning(f"⚠️ Signal-Fixes konnten nicht angewendet werden: {str(e)}") + +# ===== SICHERE SUBPROCESS-WRAPPER ===== + +def safe_subprocess_run(*args, **kwargs): + """ + Sicherer subprocess.run Wrapper für Windows mit UTF-8 Encoding. + Verhindert charmap-Fehler durch explizite Encoding-Einstellungen. + """ + import subprocess + + # Standard-Encoding für Windows setzen + if 'encoding' not in kwargs and kwargs.get('text', False): + kwargs['encoding'] = 'utf-8' + kwargs['errors'] = 'replace' + + # Timeout-Standard setzen falls nicht vorhanden + if 'timeout' not in kwargs: + kwargs['timeout'] = 30 + + try: + return subprocess.run(*args, **kwargs) + except subprocess.TimeoutExpired as e: + windows_logger.warning(f"Subprocess-Timeout nach {kwargs.get('timeout', 30)}s: {' '.join(args[0]) if args and isinstance(args[0], list) else str(args)}") + raise e + except UnicodeDecodeError as e: + windows_logger.error(f"Unicode-Decode-Fehler in subprocess: {str(e)}") + # Fallback ohne text=True + kwargs_fallback = kwargs.copy() + kwargs_fallback.pop('text', None) + kwargs_fallback.pop('encoding', None) + kwargs_fallback.pop('errors', None) + return subprocess.run(*args, **kwargs_fallback) + except Exception as e: + windows_logger.error(f"Subprocess-Fehler: {str(e)}") + raise e + +# ===== SUBPROCESS-MONKEY-PATCH ===== + +def patch_subprocess(): + """ + Patcht subprocess.run und subprocess.Popen um automatisch sichere Encoding-Einstellungen zu verwenden. + """ + import subprocess + + # Original-Funktionen speichern + if not hasattr(subprocess, '_original_run'): + subprocess._original_run = subprocess.run + subprocess._original_popen = subprocess.Popen + + def patched_run(*args, **kwargs): + # Automatisch UTF-8 Encoding für text=True setzen + if kwargs.get('text', False) and 'encoding' not in kwargs: + kwargs['encoding'] = 'utf-8' + kwargs['errors'] = 'replace' + + return subprocess._original_run(*args, **kwargs) + + def patched_popen(*args, **kwargs): + # Automatisch UTF-8 Encoding für text=True setzen + if kwargs.get('text', False) and 'encoding' not in kwargs: + kwargs['encoding'] = 'utf-8' + kwargs['errors'] = 'replace' + + # Auch für universal_newlines (ältere Python-Versionen) + if kwargs.get('universal_newlines', False) and 'encoding' not in kwargs: + kwargs['encoding'] = 'utf-8' + kwargs['errors'] = 'replace' + + return subprocess._original_popen(*args, **kwargs) + + subprocess.run = patched_run + subprocess.Popen = patched_popen + windows_logger.info("✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)") + +# ===== GLOBALER SUBPROCESS-PATCH ===== + +def apply_global_subprocess_patch(): + """ + Wendet den subprocess-Patch global an, auch für bereits importierte Module. + """ + import sys + import subprocess + + # Patch subprocess direkt + patch_subprocess() + + # Patch auch in bereits importierten Modulen + for module_name, module in sys.modules.items(): + if hasattr(module, 'subprocess') and module.subprocess is subprocess: + # Modul verwendet subprocess - patch es + module.subprocess = subprocess + windows_logger.debug(f"✅ Subprocess in Modul {module_name} gepatcht") + + windows_logger.info("✅ Globaler subprocess-Patch angewendet") + +def apply_all_windows_fixes(): + """Wendet alle Windows-spezifischen Fixes an.""" + global _windows_fixes_applied + + if _windows_fixes_applied: + return + + try: + windows_logger.info("🔧 Wende Windows-spezifische Fixes an...") + + # 1. Encoding-Fixes + apply_encoding_fixes() + + # 2. Threading-Fixes + apply_threading_fixes() + + # 3. Signal-Handler-Fixes + apply_signal_fixes() + + # 4. Subprocess-Patch für UTF-8 Encoding + patch_subprocess() + + # 5. Globaler Subprocess-Patch für bereits importierte Module + apply_global_subprocess_patch() + + _windows_fixes_applied = True + windows_logger.info("✅ Alle Windows-Fixes erfolgreich angewendet") + + except Exception as e: + windows_logger.error(f"❌ Fehler beim Anwenden der Windows-Fixes: {str(e)}") + raise e + +# Automatisch Windows-Fixes beim Import anwenden (nur einmal) +if os.name == 'nt' and not _windows_fixes_applied: + try: + apply_all_windows_fixes() + except Exception as e: + windows_logger.warning(f"⚠️ Windows-Fixes konnten nicht automatisch angewendet werden: {str(e)}") \ No newline at end of file