Feature: Konfigurierbare SaxonWorkerPool-Aktivierung
Performance-Dialog erweitert um Checkbox zur Aktivierung/Deaktivierung des SaxonWorkerPool. Benutzer können jetzt zwischen Worker-Pool (schnell, benötigt JDK) und Fallback-Modus (robust, nur JRE) wählen. Änderungen: - Neue Einstellung 'use_saxon_worker_pool' in AppSettings (Standard: aktiviert) - Erweiterter Performance-Dialog mit zwei Sektionen (ThreadPoolExecutor + SaxonWorkerPool) - Pool-Initialisierung prüft nun Einstellung vor Worker-Start - Aktualisiertes Menü-Tooltip zeigt beide Einstellungen 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -143,6 +143,7 @@ class AppSettings(BaseSettings):
|
|||||||
postgresql_dbs: list[PostgreSqlDb] = []
|
postgresql_dbs: list[PostgreSqlDb] = []
|
||||||
theme: str | None = None
|
theme: str | None = None
|
||||||
max_workers: int = 8 # Anzahl paralleler Worker für Transformationen (Standard: 8)
|
max_workers: int = 8 # Anzahl paralleler Worker für Transformationen (Standard: 8)
|
||||||
|
use_saxon_worker_pool: bool = True # SaxonWorkerPool aktivieren (schneller, benötigt JDK)
|
||||||
|
|
||||||
# UI-Zustand
|
# UI-Zustand
|
||||||
window_geometry: tuple[int, int, int, int] | None = None # (x, y, width, height)
|
window_geometry: tuple[int, int, int, int] | None = None # (x, y, width, height)
|
||||||
|
|||||||
+105
-15
@@ -655,7 +655,10 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# Erstelle Aktion für Performance-Einstellungen
|
# Erstelle Aktion für Performance-Einstellungen
|
||||||
performance_action = QAction("Performance-Einstellungen...", self)
|
performance_action = QAction("Performance-Einstellungen...", self)
|
||||||
performance_action.setToolTip(f"Parallele Worker: {app_settings.max_workers}")
|
pool_status = "aktiviert" if app_settings.use_saxon_worker_pool else "deaktiviert"
|
||||||
|
performance_action.setToolTip(
|
||||||
|
f"Worker: {app_settings.max_workers} | SaxonWorkerPool: {pool_status}"
|
||||||
|
)
|
||||||
performance_action.triggered.connect(self._open_performance_settings)
|
performance_action.triggered.connect(self._open_performance_settings)
|
||||||
|
|
||||||
# Füge die Aktion zum Projekt-Menü hinzu
|
# Füge die Aktion zum Projekt-Menü hinzu
|
||||||
@@ -665,28 +668,109 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def _open_performance_settings(self):
|
def _open_performance_settings(self):
|
||||||
"""Öffnet einen Dialog für Performance-Einstellungen."""
|
"""Öffnet einen Dialog für Performance-Einstellungen."""
|
||||||
from PySide6.QtWidgets import QInputDialog
|
from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QSpinBox, QCheckBox, QPushButton, QGroupBox
|
||||||
|
|
||||||
current_workers = app_settings.max_workers
|
# Erstelle benutzerdefinierten Dialog
|
||||||
new_workers, ok = QInputDialog.getInt(
|
dialog = QDialog(self)
|
||||||
self,
|
dialog.setWindowTitle("Performance-Einstellungen")
|
||||||
"Performance-Einstellungen",
|
dialog.setMinimumWidth(450)
|
||||||
"Anzahl paralleler Worker für Transformationen:",
|
|
||||||
current_workers, # value
|
layout = QVBoxLayout()
|
||||||
1, # minValue
|
|
||||||
32, # maxValue
|
# Worker-Anzahl Einstellung
|
||||||
1, # step
|
worker_group = QGroupBox("ThreadPoolExecutor Einstellungen")
|
||||||
|
worker_layout = QVBoxLayout()
|
||||||
|
|
||||||
|
worker_label = QLabel("Anzahl paralleler Worker für Transformationen:")
|
||||||
|
worker_spinbox = QSpinBox()
|
||||||
|
worker_spinbox.setMinimum(1)
|
||||||
|
worker_spinbox.setMaximum(32)
|
||||||
|
worker_spinbox.setValue(app_settings.max_workers)
|
||||||
|
worker_spinbox.setToolTip("Anzahl der parallelen Worker-Threads für Transformationen (Standard: 8)")
|
||||||
|
|
||||||
|
worker_layout.addWidget(worker_label)
|
||||||
|
worker_layout.addWidget(worker_spinbox)
|
||||||
|
worker_group.setLayout(worker_layout)
|
||||||
|
layout.addWidget(worker_group)
|
||||||
|
|
||||||
|
# SaxonWorkerPool Einstellung
|
||||||
|
pool_group = QGroupBox("SaxonWorkerPool Einstellungen")
|
||||||
|
pool_layout = QVBoxLayout()
|
||||||
|
|
||||||
|
pool_checkbox = QCheckBox("SaxonWorkerPool verwenden (empfohlen)")
|
||||||
|
pool_checkbox.setChecked(app_settings.use_saxon_worker_pool)
|
||||||
|
pool_checkbox.setToolTip(
|
||||||
|
"Aktiviert persistente JVM-Prozesse für Saxon-Transformationen.\n"
|
||||||
|
"Vorteile: Bis zu 10x schneller durch Eliminierung von JVM-Startup-Overhead\n"
|
||||||
|
"Nachteile: Benötigt JDK (javac) - funktioniert nicht mit JRE allein\n\n"
|
||||||
|
"Deaktivieren Sie diese Option, wenn:\n"
|
||||||
|
"• Sie nur ein JRE (keine JDK) installiert haben\n"
|
||||||
|
"• Sie Probleme mit dem Worker-Pool haben\n"
|
||||||
|
"• Sie die Funktion testen möchten"
|
||||||
)
|
)
|
||||||
|
|
||||||
if ok and new_workers != current_workers:
|
pool_info = QLabel(
|
||||||
|
"<i>Hinweis: SaxonWorkerPool benötigt ein JDK (Java Development Kit).<br>"
|
||||||
|
"Mit JRE allein werden Transformationen im Fallback-Modus ausgeführt.</i>"
|
||||||
|
)
|
||||||
|
pool_info.setWordWrap(True)
|
||||||
|
|
||||||
|
pool_layout.addWidget(pool_checkbox)
|
||||||
|
pool_layout.addWidget(pool_info)
|
||||||
|
pool_group.setLayout(pool_layout)
|
||||||
|
layout.addWidget(pool_group)
|
||||||
|
|
||||||
|
# OK/Abbrechen Buttons
|
||||||
|
button_layout = QHBoxLayout()
|
||||||
|
ok_button = QPushButton("OK")
|
||||||
|
cancel_button = QPushButton("Abbrechen")
|
||||||
|
|
||||||
|
ok_button.clicked.connect(dialog.accept)
|
||||||
|
cancel_button.clicked.connect(dialog.reject)
|
||||||
|
|
||||||
|
button_layout.addStretch()
|
||||||
|
button_layout.addWidget(ok_button)
|
||||||
|
button_layout.addWidget(cancel_button)
|
||||||
|
layout.addLayout(button_layout)
|
||||||
|
|
||||||
|
dialog.setLayout(layout)
|
||||||
|
|
||||||
|
# Dialog anzeigen
|
||||||
|
if dialog.exec() == QDialog.DialogCode.Accepted:
|
||||||
|
# Speichere Änderungen
|
||||||
|
current_workers = app_settings.max_workers
|
||||||
|
current_use_pool = app_settings.use_saxon_worker_pool
|
||||||
|
|
||||||
|
new_workers = worker_spinbox.value()
|
||||||
|
new_use_pool = pool_checkbox.isChecked()
|
||||||
|
|
||||||
|
changes = []
|
||||||
|
|
||||||
|
if new_workers != current_workers:
|
||||||
app_settings.max_workers = new_workers
|
app_settings.max_workers = new_workers
|
||||||
app_settings.save()
|
changes.append(f"Worker-Anzahl: {current_workers} → {new_workers}")
|
||||||
logger.info(f"max_workers geändert: {current_workers} → {new_workers}")
|
logger.info(f"max_workers geändert: {current_workers} → {new_workers}")
|
||||||
|
|
||||||
|
if new_use_pool != current_use_pool:
|
||||||
|
app_settings.use_saxon_worker_pool = new_use_pool
|
||||||
|
status = "aktiviert" if new_use_pool else "deaktiviert"
|
||||||
|
changes.append(f"SaxonWorkerPool: {status}")
|
||||||
|
logger.info(f"use_saxon_worker_pool geändert: {current_use_pool} → {new_use_pool}")
|
||||||
|
|
||||||
|
if changes:
|
||||||
|
app_settings.save()
|
||||||
|
|
||||||
|
# Informiere Benutzer über Änderungen
|
||||||
|
changes_text = "\n".join(f"• {change}" for change in changes)
|
||||||
|
restart_hint = ""
|
||||||
|
|
||||||
|
if new_use_pool != current_use_pool and self.project:
|
||||||
|
restart_hint = "\n\nHinweis: Bitte öffnen Sie das Projekt neu, damit die Änderung wirksam wird."
|
||||||
|
|
||||||
QMessageBox.information(
|
QMessageBox.information(
|
||||||
self,
|
self,
|
||||||
"Einstellungen gespeichert",
|
"Einstellungen gespeichert",
|
||||||
f"Anzahl paralleler Worker wurde auf {new_workers} gesetzt.\n\n"
|
f"Folgende Einstellungen wurden geändert:\n\n{changes_text}{restart_hint}",
|
||||||
f"Die Änderung wird bei der nächsten Transformation wirksam.",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def open_existing_project(self, project: Project):
|
def open_existing_project(self, project: Project):
|
||||||
@@ -744,6 +828,11 @@ class MainWindow(QMainWindow):
|
|||||||
# Shutdown vorherigen Pool falls vorhanden
|
# Shutdown vorherigen Pool falls vorhanden
|
||||||
self._shutdown_saxon_worker_pool()
|
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:
|
if not self.project:
|
||||||
logger.warning("Kein Projekt geladen, Saxon-Worker-Pool nicht initialisiert")
|
logger.warning("Kein Projekt geladen, Saxon-Worker-Pool nicht initialisiert")
|
||||||
return
|
return
|
||||||
@@ -777,6 +866,7 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Fehler beim Initialisieren des Saxon-Worker-Pools: {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
|
# Kein Pool ist OK - Fallback auf subprocess
|
||||||
|
|
||||||
def _shutdown_saxon_worker_pool(self):
|
def _shutdown_saxon_worker_pool(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user