puda-comms 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- puda_comms/__init__.py +5 -0
- puda_comms/command_service.py +635 -0
- puda_comms/execution_state.py +89 -0
- puda_comms/machine_client.py +771 -0
- puda_comms/models.py +88 -0
- puda_comms-0.0.2.dist-info/METADATA +310 -0
- puda_comms-0.0.2.dist-info/RECORD +8 -0
- puda_comms-0.0.2.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Execution State Management
|
|
3
|
+
Provides thread-safe state tracking for command execution and cancellation.
|
|
4
|
+
"""
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ExecutionState:
|
|
13
|
+
"""
|
|
14
|
+
Shared state for tracking command execution and cancellation.
|
|
15
|
+
|
|
16
|
+
This class provides thread-safe access to:
|
|
17
|
+
- Current executing task (for cancellation)
|
|
18
|
+
- Execution lock (to prevent concurrent commands)
|
|
19
|
+
- Current run_id (to match cancel with execute)
|
|
20
|
+
"""
|
|
21
|
+
def __init__(self):
|
|
22
|
+
self._lock = asyncio.Lock()
|
|
23
|
+
self._current_task: Optional[asyncio.Task] = None
|
|
24
|
+
self._current_run_id: Optional[str] = None
|
|
25
|
+
self._cancelled = False
|
|
26
|
+
|
|
27
|
+
async def acquire_lock(self, run_id: str) -> bool:
|
|
28
|
+
"""
|
|
29
|
+
Acquire the execution lock for a command.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
run_id: Run ID of the command requesting execution
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
True if execution can proceed, False if cancelled or another command is running
|
|
36
|
+
"""
|
|
37
|
+
await self._lock.acquire()
|
|
38
|
+
if self._cancelled:
|
|
39
|
+
self._lock.release()
|
|
40
|
+
return False
|
|
41
|
+
self._current_run_id = run_id
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
def release_lock(self):
|
|
45
|
+
"""Release the execution lock."""
|
|
46
|
+
self._current_run_id = None
|
|
47
|
+
self._current_task = None
|
|
48
|
+
self._cancelled = False
|
|
49
|
+
self._lock.release()
|
|
50
|
+
|
|
51
|
+
def set_current_task(self, task: asyncio.Task):
|
|
52
|
+
"""Set the currently executing task (for cancellation)."""
|
|
53
|
+
self._current_task = task
|
|
54
|
+
|
|
55
|
+
def get_current_task(self) -> Optional[asyncio.Task]:
|
|
56
|
+
"""Get the currently executing task."""
|
|
57
|
+
return self._current_task
|
|
58
|
+
|
|
59
|
+
def get_current_run_id(self) -> Optional[str]:
|
|
60
|
+
"""Get the current run_id."""
|
|
61
|
+
return self._current_run_id
|
|
62
|
+
|
|
63
|
+
async def cancel_current_execution(self, run_id: Optional[str] = None) -> bool:
|
|
64
|
+
"""
|
|
65
|
+
Cancel the currently executing command.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
run_id: Optional run_id to match. If provided, only cancels if it matches.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
True if cancellation was successful, False if no execution to cancel
|
|
72
|
+
"""
|
|
73
|
+
if self._current_task is None:
|
|
74
|
+
return False
|
|
75
|
+
|
|
76
|
+
# If run_id provided, only cancel if it matches
|
|
77
|
+
if run_id is not None and self._current_run_id != run_id:
|
|
78
|
+
logger.warning("Cancel run_id %s doesn't match current run_id %s",
|
|
79
|
+
run_id, self._current_run_id)
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
if not self._current_task.done():
|
|
83
|
+
logger.info("Cancelling execution (run_id: %s)", self._current_run_id)
|
|
84
|
+
self._cancelled = True
|
|
85
|
+
self._current_task.cancel()
|
|
86
|
+
return True
|
|
87
|
+
|
|
88
|
+
return False
|
|
89
|
+
|