Update changes
Dieser Commit ist enthalten in:
@ -8,19 +8,23 @@ from typing import Dict, Any, Optional
|
||||
from utils.text_similarity import TextSimilarity
|
||||
from domain.value_objects.browser_protection_style import BrowserProtectionStyle, ProtectionLevel
|
||||
import traceback
|
||||
import logging
|
||||
import threading
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BaseAccountCreationWorkerThread(QThread):
|
||||
"""Basis-Klasse für alle Platform Worker Threads"""
|
||||
|
||||
|
||||
# Signals MÜSSEN identisch zu bestehenden sein
|
||||
update_signal = pyqtSignal(str)
|
||||
log_signal = pyqtSignal(str)
|
||||
progress_signal = pyqtSignal(int)
|
||||
finished_signal = pyqtSignal(dict)
|
||||
error_signal = pyqtSignal(str)
|
||||
|
||||
def __init__(self, params: Dict[str, Any], platform_name: str,
|
||||
|
||||
def __init__(self, params: Dict[str, Any], platform_name: str,
|
||||
session_controller: Optional[Any] = None,
|
||||
generator_tab: Optional[Any] = None):
|
||||
super().__init__()
|
||||
@ -29,10 +33,19 @@ class BaseAccountCreationWorkerThread(QThread):
|
||||
self.session_controller = session_controller
|
||||
self.generator_tab = generator_tab
|
||||
self.running = True
|
||||
|
||||
|
||||
# Thread-Safety Lock für Guard-Flags
|
||||
self._guard_lock = threading.Lock()
|
||||
|
||||
# Flag: Wurde der Worker durch User-Abbruch gestoppt?
|
||||
self._was_cancelled = False
|
||||
|
||||
# Flag: Wurde Guard bereits vom Worker freigegeben?
|
||||
self._guard_released = False
|
||||
|
||||
# TextSimilarity für robustes Fehler-Matching
|
||||
self.text_similarity = TextSimilarity(default_threshold=0.8)
|
||||
|
||||
|
||||
# Platform-spezifische Error-Patterns (überschreibbar)
|
||||
self.error_interpretations = self.get_error_interpretations()
|
||||
|
||||
@ -209,10 +222,8 @@ class BaseAccountCreationWorkerThread(QThread):
|
||||
self.progress_signal.emit(0) # Reset progress on error
|
||||
|
||||
finally:
|
||||
# Feature 5: Process Guard freigeben
|
||||
from utils.process_guard import get_guard
|
||||
guard = get_guard()
|
||||
guard.end(success)
|
||||
# Process Guard freigeben (thread-safe)
|
||||
self._release_guard_if_needed(success)
|
||||
|
||||
def _interpret_error(self, error_message: str) -> str:
|
||||
"""Interpretiert Fehler mit Fuzzy-Matching"""
|
||||
@ -282,24 +293,47 @@ class BaseAccountCreationWorkerThread(QThread):
|
||||
|
||||
return save_result
|
||||
|
||||
def _release_guard_if_needed(self, success: bool = False, is_cancel: bool = False):
|
||||
"""
|
||||
Thread-safe Guard-Freigabe.
|
||||
|
||||
Args:
|
||||
success: War der Prozess erfolgreich? (nur relevant bei end())
|
||||
is_cancel: Wird von stop() aufgerufen? (erzwingt release())
|
||||
"""
|
||||
with self._guard_lock:
|
||||
if self._guard_released:
|
||||
# Bereits freigegeben - nichts zu tun
|
||||
return
|
||||
|
||||
# Wenn von stop() aufgerufen, IMMER als Cancel markieren
|
||||
if is_cancel:
|
||||
self._was_cancelled = True
|
||||
|
||||
from utils.process_guard import get_guard
|
||||
guard = get_guard()
|
||||
|
||||
if self._was_cancelled:
|
||||
# User-Abbruch: release() zählt nicht als Failure
|
||||
guard.release()
|
||||
logger.info(f"{self.platform_name}: Guard released (User-Abbruch)")
|
||||
else:
|
||||
# Normale Beendigung: end() mit Erfolgs-Status
|
||||
guard.end(success)
|
||||
logger.info(f"{self.platform_name}: Guard ended (success={success})")
|
||||
|
||||
self._guard_released = True
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stoppt den Thread sauber mit Guard-Freigabe.
|
||||
|
||||
WICHTIG: Guard wird SOFORT freigegeben, da terminate() den finally-Block überspringt.
|
||||
User-Abbruch wird mit release() behandelt (zählt NICHT als Failure).
|
||||
"""
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
self.running = False
|
||||
|
||||
# Guard SOFORT freigeben bevor terminate()
|
||||
# Grund: terminate() überspringt den finally-Block in run()
|
||||
from utils.process_guard import get_guard
|
||||
guard = get_guard()
|
||||
if guard.is_locked():
|
||||
guard.end(success=False)
|
||||
logger.info("Guard freigegeben bei Worker-Stop (vor terminate)")
|
||||
# Guard thread-safe freigeben (is_cancel=True setzt _was_cancelled im Lock)
|
||||
self._release_guard_if_needed(is_cancel=True)
|
||||
|
||||
# Jetzt Thread beenden
|
||||
self.terminate()
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren