commandnet 0.6.1__tar.gz → 0.6.3__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.
- {commandnet-0.6.1 → commandnet-0.6.3}/PKG-INFO +1 -1
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/engine/runtime.py +41 -17
- {commandnet-0.6.1 → commandnet-0.6.3}/pyproject.toml +1 -1
- {commandnet-0.6.1 → commandnet-0.6.3}/README.md +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/__init__.py +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/core/graph.py +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/core/models.py +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/core/node.py +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/interfaces/event_bus.py +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/interfaces/observer.py +0 -0
- {commandnet-0.6.1 → commandnet-0.6.3}/commandnet/interfaces/persistence.py +0 -0
|
@@ -48,7 +48,12 @@ class Engine:
|
|
|
48
48
|
# --- CORE WORKER LOGIC ---
|
|
49
49
|
|
|
50
50
|
async def process_event(self, event: Event):
|
|
51
|
-
|
|
51
|
+
if event.node_name == "__SIGNAL_RELEASE__":
|
|
52
|
+
signal_id = event.payload.get("signal_id")
|
|
53
|
+
signal_data = event.payload.get("data")
|
|
54
|
+
await self._handle_distributed_signal(signal_id, signal_data)
|
|
55
|
+
return
|
|
56
|
+
|
|
52
57
|
if event.node_name == "__CONTROL__":
|
|
53
58
|
action = (event.payload or {}).get("action")
|
|
54
59
|
if action == "HARD_CANCEL" and event.subject_id in self._active_tasks:
|
|
@@ -69,6 +74,25 @@ class Engine:
|
|
|
69
74
|
finally:
|
|
70
75
|
self._active_tasks.pop(event.subject_id, None)
|
|
71
76
|
|
|
77
|
+
async def _handle_distributed_signal(self, signal_id: str, payload: Any):
|
|
78
|
+
"""
|
|
79
|
+
One worker picks up the signal release event and converts
|
|
80
|
+
parked subjects into active events.
|
|
81
|
+
"""
|
|
82
|
+
# 1. Find all subjects waiting on this signal in the DB
|
|
83
|
+
waiters = await self.db.get_and_clear_waiters(signal_id)
|
|
84
|
+
|
|
85
|
+
for waiter in waiters:
|
|
86
|
+
subject_id = waiter["subject_id"]
|
|
87
|
+
# 2. For each waiter, trigger a standard resume turn
|
|
88
|
+
# This puts a specific task-event back on the RabbitMQ queue
|
|
89
|
+
await self._apply_target(
|
|
90
|
+
subject_id=subject_id,
|
|
91
|
+
context=waiter["context"],
|
|
92
|
+
target=waiter["next_target"],
|
|
93
|
+
payload=payload
|
|
94
|
+
)
|
|
95
|
+
|
|
72
96
|
async def _run_node_logic(self, event: Event):
|
|
73
97
|
subject_id = event.subject_id
|
|
74
98
|
|
|
@@ -115,7 +139,8 @@ class Engine:
|
|
|
115
139
|
result = Interrupt(subject_id=subject_id, hard=True)
|
|
116
140
|
|
|
117
141
|
duration = (asyncio.get_event_loop().time() - start_t) * 1000
|
|
118
|
-
|
|
142
|
+
|
|
143
|
+
await self._apply_target(subject_id, ctx, result, duration, payload=payload)
|
|
119
144
|
|
|
120
145
|
except Exception as e:
|
|
121
146
|
await self.observer.on_error(subject_id, event.node_name, e)
|
|
@@ -379,25 +404,24 @@ class Engine:
|
|
|
379
404
|
)
|
|
380
405
|
|
|
381
406
|
result = await node_inst.on_signal(ctx, signal_id, payload)
|
|
382
|
-
await self._apply_target(subject_id, ctx, result)
|
|
407
|
+
await self._apply_target(subject_id, ctx, result, payload=payload)
|
|
383
408
|
finally:
|
|
384
409
|
await self.db.unlock_subject(subject_id)
|
|
385
410
|
|
|
386
411
|
async def release_signal(self, signal_id: str, payload: Any = None):
|
|
387
|
-
"""
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
await self.db.unlock_subject(subject_id)
|
|
412
|
+
"""
|
|
413
|
+
NEW: Instead of processing locally, broadcast the signal
|
|
414
|
+
to the entire cluster via the EventBus.
|
|
415
|
+
"""
|
|
416
|
+
sig_event = Event(
|
|
417
|
+
subject_id="__GLOBAL__",
|
|
418
|
+
node_name="__SIGNAL_RELEASE__",
|
|
419
|
+
payload={
|
|
420
|
+
"signal_id": signal_id,
|
|
421
|
+
"data": payload
|
|
422
|
+
}
|
|
423
|
+
)
|
|
424
|
+
await self.bus.publish(sig_event)
|
|
401
425
|
|
|
402
426
|
async def cancel_subject(self, subject_id: str, hard: bool = True):
|
|
403
427
|
await self.db.set_cancel_flag(subject_id, hard)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "commandnet"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.3"
|
|
4
4
|
description = "A lightweight, Pydantic-powered, distributed event-driven state machine and typed node graph runtime."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Christopher Vaz", email = "christophervaz160@gmail.com" }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|