Refactor: MainWindow in 7 Mixins aufgeteilt (80% Code-Reduktion)
MainWindow.py von 5025 auf 983 Zeilen reduziert durch Extraktion in: - TreeManagerMixin: Baumstruktur-Verwaltung (~1136 Zeilen) - PdfViewerMixin: PDF-Anzeige und Rendering - WorkerPoolMixin: Saxon/FOP Worker-Pool-Verwaltung - DatabaseMixin: PostgreSQL-Operationen - DragDropMixin: Drag-and-Drop für XML-Dateien - HashCalculationMixin: blake2b Hash-Berechnung - TransformationMixin: XSL-Transformationen Zusätzlich Thread-Klassen in threads.py ausgelagert. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
"""
|
||||
WorkerPoolMixin - Mixin für Worker-Pool-Verwaltung.
|
||||
|
||||
Dieses Mixin enthält alle Methoden zur Verwaltung der Saxon- und FOP-Worker-Pools
|
||||
für das MainWindow.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from PySide6.QtWidgets import QMessageBox
|
||||
|
||||
from conf import app_settings, XsltVersion
|
||||
from transform import TransformationJob, set_saxon_worker_pool
|
||||
from saxon_pool import SaxonWorkerPool
|
||||
from saxon_pool_s9api import SaxonWorkerPoolS9Api
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WorkerPoolMixin:
|
||||
"""
|
||||
Mixin für Worker-Pool-Verwaltung.
|
||||
|
||||
Dieses Mixin wird von MainWindow verwendet und erwartet folgende Attribute:
|
||||
- self.project: Das aktuelle Projekt
|
||||
"""
|
||||
|
||||
def _initialize_saxon_worker_pool(self):
|
||||
"""Initialisiert den Saxon-Worker-Pool für schnelle Transformationen."""
|
||||
try:
|
||||
# Shutdown vorherigen Pool falls vorhanden
|
||||
self._shutdown_saxon_worker_pool()
|
||||
|
||||
# Prüfe ob SaxonWorkerPool aktiviert ist
|
||||
if not app_settings.use_saxon_worker_pool:
|
||||
logger.info("SaxonWorkerPool deaktiviert - Verwende Fallback-Modus (subprocess)")
|
||||
return
|
||||
|
||||
if not self.project:
|
||||
logger.warning("Kein Projekt geladen, Saxon-Worker-Pool nicht initialisiert")
|
||||
return
|
||||
|
||||
# Hole Tool-Konfigurationen
|
||||
java_vm = next((vm for vm in app_settings.java_vms if vm.id == self.project.java_vm_id), None)
|
||||
saxon_jar = next((jar for jar in app_settings.saxon_jars if jar.id == self.project.saxon_jar_id), None)
|
||||
|
||||
if not java_vm or not saxon_jar:
|
||||
logger.warning("Java VM oder Saxon JAR nicht gefunden, Pool nicht initialisiert")
|
||||
return
|
||||
|
||||
# Erstelle Worker-Pool (wähle richtige Variante basierend auf XSLT-Version)
|
||||
num_workers = app_settings.max_workers
|
||||
log_dir = self.project.project_dir / "temp"
|
||||
|
||||
# Wähle die richtige Worker-Pool-Implementierung
|
||||
if app_settings.saxon_xslt_version == XsltVersion.XSLT_1_0:
|
||||
# JAXP-basierte Variante für XSLT 1.0
|
||||
pool = SaxonWorkerPool(
|
||||
num_workers=num_workers,
|
||||
java_vm_path=java_vm.path_to_binary_file,
|
||||
saxon_jar_path=saxon_jar.path_to_jar_file,
|
||||
classpath_cache=TransformationJob._classpath_cache,
|
||||
log_dir=log_dir,
|
||||
)
|
||||
pool_type = "JAXP (XSLT 1.0)"
|
||||
else:
|
||||
# s9api-basierte Variante für XSLT 2.0/3.0
|
||||
pool = SaxonWorkerPoolS9Api(
|
||||
num_workers=num_workers,
|
||||
java_vm_path=java_vm.path_to_binary_file,
|
||||
saxon_jar_path=saxon_jar.path_to_jar_file,
|
||||
classpath_cache=TransformationJob._classpath_cache,
|
||||
log_dir=log_dir,
|
||||
)
|
||||
pool_type = "s9api (XSLT 2.0/3.0)"
|
||||
|
||||
# Setze globalen Pool
|
||||
set_saxon_worker_pool(pool)
|
||||
|
||||
logger.info(
|
||||
f"Saxon-Worker-Pool initialisiert: {num_workers} Worker mit {pool_type} "
|
||||
f"(erwartet: {num_workers}x schneller für Saxon-Transformationen)"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Initialisieren des Saxon-Worker-Pools: {e}")
|
||||
logger.info("Fallback auf subprocess-Modus")
|
||||
# Kein Pool ist OK - Fallback auf subprocess
|
||||
|
||||
def _shutdown_saxon_worker_pool(self):
|
||||
"""Beendet den Saxon-Worker-Pool sauber."""
|
||||
try:
|
||||
# Importiere transform um Zugriff auf globalen Pool zu haben
|
||||
import transform
|
||||
|
||||
if transform._saxon_worker_pool:
|
||||
logger.info("Beende Saxon-Worker-Pool...")
|
||||
transform._saxon_worker_pool.shutdown()
|
||||
set_saxon_worker_pool(None)
|
||||
logger.info("Saxon-Worker-Pool beendet")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Beenden des Saxon-Worker-Pools: {e}")
|
||||
|
||||
def _initialize_fop_worker_pool(self):
|
||||
"""Initialisiert den FOP-Worker-Pool für schnelle PDF-Generierung."""
|
||||
try:
|
||||
# Shutdown vorherigen Pool falls vorhanden
|
||||
self._shutdown_fop_worker_pool()
|
||||
|
||||
# Prüfe ob FopWorkerPool aktiviert ist
|
||||
if not app_settings.use_fop_worker_pool:
|
||||
logger.info("FopWorkerPool deaktiviert - Verwende Fallback-Modus (subprocess)")
|
||||
return
|
||||
|
||||
if not self.project:
|
||||
logger.warning("Kein Projekt geladen, FOP-Worker-Pool nicht initialisiert")
|
||||
return
|
||||
|
||||
# Hole Tool-Konfigurationen
|
||||
java_vm = next((vm for vm in app_settings.java_vms if vm.id == self.project.java_vm_id), None)
|
||||
apache_fop = next((fop for fop in app_settings.apache_fops if fop.id == self.project.apache_fop_id), None)
|
||||
|
||||
if not java_vm or not apache_fop:
|
||||
logger.warning("Java VM oder Apache FOP nicht gefunden, Pool nicht initialisiert")
|
||||
return
|
||||
|
||||
# FOP-Konfigurationsdatei (falls vorhanden)
|
||||
fop_config_file = None
|
||||
if self.project.fop_config_dir:
|
||||
fop_config_file = self.project.fop_config_dir / "fop.xconf"
|
||||
else:
|
||||
default_config = apache_fop.path_to_dir / "conf" / "fop.xconf"
|
||||
if default_config.exists():
|
||||
fop_config_file = default_config
|
||||
|
||||
# Importiere FopWorkerPool
|
||||
from fop_pool import FopWorkerPool
|
||||
from transform import set_fop_worker_pool
|
||||
|
||||
# Erstelle Worker-Pool
|
||||
num_workers = app_settings.max_workers
|
||||
log_dir = self.project.project_dir / "temp"
|
||||
pool = FopWorkerPool(
|
||||
num_workers=num_workers,
|
||||
java_vm_path=java_vm.path_to_binary_file,
|
||||
apache_fop_dir=apache_fop.path_to_dir,
|
||||
fop_config_file=fop_config_file,
|
||||
log_dir=log_dir,
|
||||
)
|
||||
|
||||
# Setze globalen Pool
|
||||
set_fop_worker_pool(pool)
|
||||
|
||||
logger.info(
|
||||
f"FOP-Worker-Pool initialisiert: {num_workers} Worker "
|
||||
f"(erwartet: {num_workers}x schneller für PDF-Generierung)"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Initialisieren des FOP-Worker-Pools: {e}")
|
||||
logger.info("Fallback auf subprocess-Modus")
|
||||
# Kein Pool ist OK - Fallback auf subprocess
|
||||
|
||||
def _shutdown_fop_worker_pool(self):
|
||||
"""Beendet den FOP-Worker-Pool sauber."""
|
||||
try:
|
||||
# Importiere transform um Zugriff auf globalen Pool zu haben
|
||||
import transform
|
||||
|
||||
if transform._fop_worker_pool:
|
||||
logger.info("Beende FOP-Worker-Pool...")
|
||||
transform._fop_worker_pool.shutdown()
|
||||
# Importiere set_fop_worker_pool
|
||||
from transform import set_fop_worker_pool
|
||||
|
||||
set_fop_worker_pool(None)
|
||||
logger.info("FOP-Worker-Pool beendet")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Beenden des FOP-Worker-Pools: {e}")
|
||||
|
||||
def _show_worker_pool_metrics(self):
|
||||
"""Zeigt den Worker-Pool-Metriken-Dialog an."""
|
||||
try:
|
||||
from ui.WorkerPoolMetricsDialog import WorkerPoolMetricsDialog
|
||||
|
||||
dialog = WorkerPoolMetricsDialog(self)
|
||||
dialog.exec()
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Öffnen des Metriken-Dialogs: {e}")
|
||||
QMessageBox.critical(self, "Fehler", f"Fehler beim Öffnen des Metriken-Dialogs:\n{str(e)}")
|
||||
Reference in New Issue
Block a user