Просмотр исходного кода

Fix stop timeout during pause and stale "waiting" UI state

Two issues fixed:

1. Stop/skip during manual pause could hang indefinitely:
   - The event wait had no timeout, relying solely on asyncio.Event
   - If stop was called from sync context (no event loop), events weren't set
   - Added 1-second timeout to ensure flags are polled as fallback

2. "Waiting for next pattern" shown during pattern playback:
   - Single pattern execution didn't clear pause_time_remaining
   - Stale values from previous playlist caused incorrect UI state
   - Now cleared at start of run_theta_rho_file()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris 2 недель назад
Родитель
Сommit
766f8c44f3
1 измененных файлов с 9 добавлено и 1 удалено
  1. 9 1
      modules/core/pattern_manager.py

+ 9 - 1
modules/core/pattern_manager.py

@@ -967,7 +967,7 @@ async def _execute_pattern_internal(file_path):
 
 
                     if state.pause_requested:
                     if state.pause_requested:
                         # For manual pause, wait on multiple events for immediate response
                         # For manual pause, wait on multiple events for immediate response
-                        # Wake on: resume, stop, or skip
+                        # Wake on: resume, stop, skip, or timeout (for flag polling fallback)
                         pause_event = get_pause_event()
                         pause_event = get_pause_event()
                         stop_event = state.get_stop_event()
                         stop_event = state.get_stop_event()
                         skip_event = state.get_skip_event()
                         skip_event = state.get_skip_event()
@@ -977,6 +977,10 @@ async def _execute_pattern_internal(file_path):
                             wait_tasks.append(asyncio.create_task(stop_event.wait(), name='stop'))
                             wait_tasks.append(asyncio.create_task(stop_event.wait(), name='stop'))
                         if skip_event:
                         if skip_event:
                             wait_tasks.append(asyncio.create_task(skip_event.wait(), name='skip'))
                             wait_tasks.append(asyncio.create_task(skip_event.wait(), name='skip'))
+                        # Add timeout to ensure we periodically check flags even if events aren't set
+                        # This handles the case where stop is called from sync context (no event loop)
+                        timeout_task = asyncio.create_task(asyncio.sleep(1.0), name='timeout')
+                        wait_tasks.append(timeout_task)
 
 
                         try:
                         try:
                             done, pending = await asyncio.wait(
                             done, pending = await asyncio.wait(
@@ -1085,6 +1089,10 @@ async def run_theta_rho_file(file_path, is_playlist=False, clear_pattern=None, c
         return
         return
 
 
     async with lock:  # This ensures only one pattern can run at a time
     async with lock:  # This ensures only one pattern can run at a time
+        # Clear any stale pause state from previous playlist
+        state.pause_time_remaining = 0
+        state.original_pause_time = None
+
         # Start progress update task only if not part of a playlist
         # Start progress update task only if not part of a playlist
         global progress_update_task
         global progress_update_task
         if not is_playlist and not progress_update_task:
         if not is_playlist and not progress_update_task: