inorbit-edge-executor 3.2.3__tar.gz → 3.2.4__tar.gz

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.
Files changed (28) hide show
  1. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/PKG-INFO +1 -1
  2. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/worker.py +5 -0
  3. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/worker_pool.py +44 -3
  4. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor.egg-info/PKG-INFO +1 -1
  5. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/pyproject.toml +2 -2
  6. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/LICENSE +0 -0
  7. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/README.md +0 -0
  8. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/__init__.py +0 -0
  9. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/behavior_tree.py +0 -0
  10. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/datatypes.py +0 -0
  11. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/db.py +0 -0
  12. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/dummy_backend.py +0 -0
  13. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/exceptions.py +0 -0
  14. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/inorbit.py +0 -0
  15. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/logger.py +0 -0
  16. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/mission.py +0 -0
  17. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/observable.py +0 -0
  18. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor/sqlite_backend.py +0 -0
  19. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor.egg-info/SOURCES.txt +0 -0
  20. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor.egg-info/dependency_links.txt +0 -0
  21. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor.egg-info/requires.txt +0 -0
  22. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/inorbit_edge_executor.egg-info/top_level.txt +0 -0
  23. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/setup.cfg +0 -0
  24. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/tests/test_behavior_tree.py +0 -0
  25. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/tests/test_behavior_tree_error_handler.py +0 -0
  26. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/tests/test_run_action_node.py +0 -0
  27. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/tests/test_set_data_node.py +0 -0
  28. {inorbit_edge_executor-3.2.3 → inorbit_edge_executor-3.2.4}/tests/test_wait_expression_node.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inorbit_edge_executor
3
- Version: 3.2.3
3
+ Version: 3.2.4
4
4
  Summary: InOrbit Edge Missions Executor
5
5
  Author-email: Mariano Cereda <mariano.cereda@inorbit.ai>, Hernan Badenes <herchu@inorbit.ai>, Miguel Garcia <mike@inorbit.ai>
6
6
  License: MIT
@@ -38,6 +38,7 @@ class Worker(Observable):
38
38
  self._robot_api_factory = None
39
39
  self._behavior_tree = None
40
40
  self._shared_memory = shared_memory
41
+ self._task: asyncio.Task = None
41
42
 
42
43
  def id(self):
43
44
  return self._mission.id
@@ -133,6 +134,10 @@ class Worker(Observable):
133
134
  self.set_paused(True)
134
135
  self._task.cancel(CANCEL_TASK_PAUSE_MESSAGE)
135
136
 
137
+ def get_task(self) -> asyncio.Task | None:
138
+ """Get the task associated with the worker. This is used to wait for the task to complete during shutdown."""
139
+ return self._task
140
+
136
141
  async def resume(self):
137
142
  """
138
143
  Resumes the worker if it was paused. Returns True if the worker was paused and resumed, False otherwise.
@@ -103,12 +103,53 @@ class WorkerPool:
103
103
  for worker_state in serialized_workers:
104
104
  await self.execute_serialized_worker(worker_state)
105
105
 
106
- async def shutdown(self):
106
+ async def shutdown(self, timeout: float = 10.0):
107
107
  """
108
- Stops the worker pool. It's actually not doing anything more than preventing new jobs
109
- to be submitted.
108
+ Stops the worker pool gracefully by cancelling all running tasks.
109
+
110
+ Args:
111
+ timeout: Maximum time to wait for graceful shutdown before forcing cancellation
110
112
  """
113
+ if not self._running:
114
+ return
115
+
111
116
  self._running = False
117
+ logger.info("Starting worker pool shutdown...")
118
+
119
+ # Get all running workers and cancel them
120
+ async with self._mutex:
121
+ workers_to_cancel = list(self._workers.values())
122
+
123
+ if workers_to_cancel:
124
+ logger.info(f"Cancelling {len(workers_to_cancel)} running workers...")
125
+
126
+ # Cancel all workers and collect their tasks
127
+ cancelled_tasks = []
128
+ for worker in workers_to_cancel:
129
+ try:
130
+ if worker.cancel():
131
+ cancelled_tasks.append(worker.get_task())
132
+ except Exception as e:
133
+ logger.error(f"Error cancelling worker {worker.id()}: {e}")
134
+
135
+ if cancelled_tasks:
136
+ # Wait for tasks to complete cancellation with timeout
137
+ try:
138
+ await asyncio.wait_for(
139
+ asyncio.gather(*cancelled_tasks, return_exceptions=True), timeout=timeout
140
+ )
141
+ logger.info("All workers cancelled gracefully")
142
+ except asyncio.TimeoutError:
143
+ logger.warning(f"Timeout waiting for graceful shutdown after {timeout}s")
144
+ else:
145
+ logger.info("No running workers to cancel")
146
+
147
+ # Clean up workers dictionary
148
+ async with self._mutex:
149
+ self._workers.clear()
150
+
151
+ # Shutdown the database connection
152
+ await self._db.shutdown()
112
153
 
113
154
  async def notify(self, worker: Worker):
114
155
  """Notified when a worker changed its state. Persist it"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inorbit_edge_executor
3
- Version: 3.2.3
3
+ Version: 3.2.4
4
4
  Summary: InOrbit Edge Missions Executor
5
5
  Author-email: Mariano Cereda <mariano.cereda@inorbit.ai>, Hernan Badenes <herchu@inorbit.ai>, Miguel Garcia <mike@inorbit.ai>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "inorbit_edge_executor"
7
- version = "3.2.3"
7
+ version = "3.2.4"
8
8
  description = "InOrbit Edge Missions Executor"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -47,7 +47,7 @@ target-version = ['py310']
47
47
  line-length = 100
48
48
 
49
49
  [tool.bumpversion]
50
- current_version = "3.2.3"
50
+ current_version = "3.2.4"
51
51
  commit = true
52
52
  tag = true
53
53
  tag_name = "v{new_version}"