Quellcode durchsuchen

fix async calls

tuanchris vor 4 Monaten
Ursprung
Commit
4eabe85c3e
2 geänderte Dateien mit 29 neuen und 30 gelöschten Zeilen
  1. 20 6
      main.py
  2. 9 24
      modules/core/pattern_manager.py

+ 20 - 6
main.py

@@ -547,7 +547,7 @@ async def stop_execution():
     if not (state.conn.is_connected() if state.conn else False):
         logger.warning("Attempted to stop without a connection")
         raise HTTPException(status_code=400, detail="Connection not established")
-    pattern_manager.stop_actions()
+    await pattern_manager.stop_actions()
     return {"success": True}
 
 @app.post("/send_home")
@@ -625,7 +625,7 @@ async def move_to_center():
             raise HTTPException(status_code=400, detail="Connection not established")
 
         logger.info("Moving device to center position")
-        pattern_manager.reset_theta()
+        await pattern_manager.reset_theta()
         await pattern_manager.move_polar(0, 0)
         return {"success": True}
     except Exception as e:
@@ -638,7 +638,7 @@ async def move_to_perimeter():
         if not (state.conn.is_connected() if state.conn else False):
             logger.warning("Attempted to move to perimeter without a connection")
             raise HTTPException(status_code=400, detail="Connection not established")
-        pattern_manager.reset_theta()
+        await pattern_manager.reset_theta()
         await pattern_manager.move_polar(0, 1)
         return {"success": True}
     except Exception as e:
@@ -1135,10 +1135,24 @@ def signal_handler(signum, frame):
     try:
         if state.led_controller:
             state.led_controller.set_power(0)
-        # Run cleanup operations synchronously to ensure completion
-        pattern_manager.stop_actions()
+        # Run cleanup operations - need to handle async in sync context
+        try:
+            # Try to run in existing loop if available
+            import asyncio
+            loop = asyncio.get_running_loop()
+            # If we're in an event loop, schedule the coroutine
+            import concurrent.futures
+            with concurrent.futures.ThreadPoolExecutor() as executor:
+                future = executor.submit(asyncio.run, pattern_manager.stop_actions())
+                future.result(timeout=5.0)  # Wait up to 5 seconds
+        except RuntimeError:
+            # No running loop, create a new one
+            import asyncio
+            asyncio.run(pattern_manager.stop_actions())
+        except Exception as cleanup_err:
+            logger.error(f"Error in async cleanup: {cleanup_err}")
+
         state.save()
-        
         logger.info("Cleanup completed")
     except Exception as e:
         logger.error(f"Error during cleanup: {str(e)}")

+ 9 - 24
modules/core/pattern_manager.py

@@ -293,13 +293,13 @@ async def run_theta_rho_file(file_path, is_playlist=False):
         state.execution_progress = (0, total_coordinates, None, 0)
         
         # stop actions without resetting the playlist
-        stop_actions(clear_playlist=False)
+        await stop_actions(clear_playlist=False)
 
         state.current_playing_file = file_path
         state.stop_requested = False
         logger.info(f"Starting pattern execution: {file_path}")
         logger.info(f"t: {state.current_theta}, r: {state.current_rho}")
-        reset_theta()
+        await reset_theta()
         
         start_time = time.time()
         if state.led_controller:
@@ -509,7 +509,7 @@ async def run_theta_rho_files(file_paths, pause_time=0, clear_pattern=None, run_
         
         logger.info("All requested patterns completed (or stopped) and state cleared")
 
-def stop_actions(clear_playlist = True):
+async def stop_actions(clear_playlist = True):
     """Stop all current actions."""
     try:
         with state.pause_condition:
@@ -531,22 +531,13 @@ def stop_actions(clear_playlist = True):
                     progress_update_task.cancel()
 
             state.pause_condition.notify_all()
-            # Run async function in sync context
-            try:
-                loop = asyncio.new_event_loop()
-                asyncio.set_event_loop(loop)
-                loop.run_until_complete(connection_manager.update_machine_position())
-                loop.close()
-            except Exception as update_err:
-                logger.error(f"Error updating machine position: {update_err}")
+            # Call async function directly since we're in async context
+            await connection_manager.update_machine_position()
     except Exception as e:
         logger.error(f"Error during stop_actions: {e}")
         # Ensure we still update machine position even if there's an error
         try:
-            loop = asyncio.new_event_loop()
-            asyncio.set_event_loop(loop)
-            loop.run_until_complete(connection_manager.update_machine_position())
-            loop.close()
+            await connection_manager.update_machine_position()
         except Exception as update_err:
             logger.error(f"Error updating machine position on error: {update_err}")
 
@@ -625,17 +616,11 @@ def resume_execution():
     pause_event.set()  # Set the event to resume execution
     return True
     
-def reset_theta():
+async def reset_theta():
     logger.info('Resetting Theta')
     state.current_theta = state.current_theta % (2 * pi)
-    # Run async function in sync context
-    try:
-        loop = asyncio.new_event_loop()
-        asyncio.set_event_loop(loop)
-        loop.run_until_complete(connection_manager.update_machine_position())
-        loop.close()
-    except Exception as e:
-        logger.error(f"Error updating machine position in reset_theta: {e}")
+    # Call async function directly since we're in async context
+    await connection_manager.update_machine_position()
 
 def set_speed(new_speed):
     state.speed = new_speed