kailash 0.8.4__py3-none-any.whl → 0.8.5__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.
Files changed (79) hide show
  1. kailash/__init__.py +1 -7
  2. kailash/cli/__init__.py +11 -1
  3. kailash/cli/validation_audit.py +570 -0
  4. kailash/core/actors/supervisor.py +1 -1
  5. kailash/core/resilience/circuit_breaker.py +71 -1
  6. kailash/core/resilience/health_monitor.py +172 -0
  7. kailash/edge/compliance.py +33 -0
  8. kailash/edge/consistency.py +609 -0
  9. kailash/edge/coordination/__init__.py +30 -0
  10. kailash/edge/coordination/global_ordering.py +355 -0
  11. kailash/edge/coordination/leader_election.py +217 -0
  12. kailash/edge/coordination/partition_detector.py +296 -0
  13. kailash/edge/coordination/raft.py +485 -0
  14. kailash/edge/discovery.py +63 -1
  15. kailash/edge/migration/__init__.py +19 -0
  16. kailash/edge/migration/edge_migrator.py +832 -0
  17. kailash/edge/monitoring/__init__.py +21 -0
  18. kailash/edge/monitoring/edge_monitor.py +736 -0
  19. kailash/edge/prediction/__init__.py +10 -0
  20. kailash/edge/prediction/predictive_warmer.py +591 -0
  21. kailash/edge/resource/__init__.py +102 -0
  22. kailash/edge/resource/cloud_integration.py +796 -0
  23. kailash/edge/resource/cost_optimizer.py +949 -0
  24. kailash/edge/resource/docker_integration.py +919 -0
  25. kailash/edge/resource/kubernetes_integration.py +893 -0
  26. kailash/edge/resource/platform_integration.py +913 -0
  27. kailash/edge/resource/predictive_scaler.py +959 -0
  28. kailash/edge/resource/resource_analyzer.py +824 -0
  29. kailash/edge/resource/resource_pools.py +610 -0
  30. kailash/integrations/dataflow_edge.py +261 -0
  31. kailash/mcp_server/registry_integration.py +1 -1
  32. kailash/monitoring/__init__.py +18 -0
  33. kailash/monitoring/alerts.py +646 -0
  34. kailash/monitoring/metrics.py +677 -0
  35. kailash/nodes/__init__.py +2 -0
  36. kailash/nodes/ai/semantic_memory.py +2 -2
  37. kailash/nodes/base.py +545 -0
  38. kailash/nodes/edge/__init__.py +36 -0
  39. kailash/nodes/edge/base.py +240 -0
  40. kailash/nodes/edge/cloud_node.py +710 -0
  41. kailash/nodes/edge/coordination.py +239 -0
  42. kailash/nodes/edge/docker_node.py +825 -0
  43. kailash/nodes/edge/edge_data.py +582 -0
  44. kailash/nodes/edge/edge_migration_node.py +392 -0
  45. kailash/nodes/edge/edge_monitoring_node.py +421 -0
  46. kailash/nodes/edge/edge_state.py +673 -0
  47. kailash/nodes/edge/edge_warming_node.py +393 -0
  48. kailash/nodes/edge/kubernetes_node.py +652 -0
  49. kailash/nodes/edge/platform_node.py +766 -0
  50. kailash/nodes/edge/resource_analyzer_node.py +378 -0
  51. kailash/nodes/edge/resource_optimizer_node.py +501 -0
  52. kailash/nodes/edge/resource_scaler_node.py +397 -0
  53. kailash/nodes/ports.py +676 -0
  54. kailash/runtime/local.py +344 -1
  55. kailash/runtime/validation/__init__.py +20 -0
  56. kailash/runtime/validation/connection_context.py +119 -0
  57. kailash/runtime/validation/enhanced_error_formatter.py +202 -0
  58. kailash/runtime/validation/error_categorizer.py +164 -0
  59. kailash/runtime/validation/metrics.py +380 -0
  60. kailash/runtime/validation/performance.py +615 -0
  61. kailash/runtime/validation/suggestion_engine.py +212 -0
  62. kailash/testing/fixtures.py +2 -2
  63. kailash/workflow/builder.py +230 -4
  64. kailash/workflow/contracts.py +418 -0
  65. kailash/workflow/edge_infrastructure.py +369 -0
  66. kailash/workflow/migration.py +3 -3
  67. kailash/workflow/type_inference.py +669 -0
  68. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/METADATA +43 -27
  69. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/RECORD +73 -27
  70. kailash/nexus/__init__.py +0 -21
  71. kailash/nexus/cli/__init__.py +0 -5
  72. kailash/nexus/cli/__main__.py +0 -6
  73. kailash/nexus/cli/main.py +0 -176
  74. kailash/nexus/factory.py +0 -413
  75. kailash/nexus/gateway.py +0 -545
  76. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/WHEEL +0 -0
  77. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/entry_points.txt +0 -0
  78. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/licenses/LICENSE +0 -0
  79. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,239 @@
1
+ """Edge coordination node for distributed consensus operations."""
2
+
3
+ import asyncio
4
+ from datetime import datetime
5
+ from typing import Any, Dict, List, Optional
6
+
7
+ from kailash.edge.coordination import (
8
+ EdgeLeaderElection,
9
+ GlobalOrderingService,
10
+ RaftNode,
11
+ RaftState,
12
+ )
13
+ from kailash.nodes.base import NodeParameter, register_node
14
+ from kailash.nodes.base_async import AsyncNode
15
+
16
+
17
+ @register_node()
18
+ class EdgeCoordinationNode(AsyncNode):
19
+ """Node providing distributed coordination operations for edge computing.
20
+
21
+ This node enables:
22
+ - Leader election among edge nodes
23
+ - Distributed consensus via Raft
24
+ - Global event ordering
25
+ - Split-brain prevention
26
+
27
+ Example:
28
+ ```python
29
+ # Elect leader for coordination group
30
+ workflow.add_node("EdgeCoordinationNode", "coordinator", {
31
+ "operation": "elect_leader",
32
+ "coordination_group": "cache_cluster"
33
+ })
34
+
35
+ # Propose change through consensus
36
+ workflow.add_node("EdgeCoordinationNode", "propose", {
37
+ "operation": "propose",
38
+ "coordination_group": "cache_cluster",
39
+ "proposal": {"action": "invalidate", "keys": ["user:*"]}
40
+ })
41
+ ```
42
+ """
43
+
44
+ def get_parameters(self) -> Dict[str, NodeParameter]:
45
+ """Get node parameters."""
46
+ return {
47
+ "operation": NodeParameter(
48
+ name="operation",
49
+ type=str,
50
+ required=True,
51
+ description="Operation to perform: elect_leader|get_leader|propose|global_order",
52
+ ),
53
+ "coordination_group": NodeParameter(
54
+ name="coordination_group",
55
+ type=str,
56
+ default="default",
57
+ required=False,
58
+ description="Coordination group name for isolation",
59
+ ),
60
+ "node_id": NodeParameter(
61
+ name="node_id",
62
+ type=str,
63
+ required=False,
64
+ description="Unique node ID (auto-generated if not provided)",
65
+ ),
66
+ "peers": NodeParameter(
67
+ name="peers",
68
+ type=list,
69
+ required=False,
70
+ description="List of peer node IDs",
71
+ ),
72
+ "proposal": NodeParameter(
73
+ name="proposal",
74
+ type=dict,
75
+ required=False,
76
+ description="Proposal data for consensus",
77
+ ),
78
+ "events": NodeParameter(
79
+ name="events",
80
+ type=list,
81
+ required=False,
82
+ description="Events to order globally",
83
+ ),
84
+ }
85
+
86
+ # Class-level coordination groups
87
+ _coordination_groups: Dict[str, Dict[str, Any]] = {}
88
+
89
+ def __init__(self, **config):
90
+ """Initialize coordination node."""
91
+ super().__init__(**config)
92
+
93
+ self.coordination_group = config.get("coordination_group", "default")
94
+ self.node_id = config.get("node_id", f"node_{id(self)}")
95
+ self.peers = config.get("peers", [])
96
+
97
+ # Get or create coordination group
98
+ if self.coordination_group not in self._coordination_groups:
99
+ self._coordination_groups[self.coordination_group] = {
100
+ "raft_nodes": {},
101
+ "leader_election": None,
102
+ "ordering_service": None,
103
+ }
104
+
105
+ self.group = self._coordination_groups[self.coordination_group]
106
+
107
+ # Initialize services lazily
108
+ self.raft_node: Optional[RaftNode] = None
109
+ self.leader_election: Optional[EdgeLeaderElection] = None
110
+ self.ordering_service: Optional[GlobalOrderingService] = None
111
+
112
+ # Metrics
113
+ self.metrics = {
114
+ "elections_started": 0,
115
+ "consensus_proposals": 0,
116
+ "ordering_requests": 0,
117
+ "errors": 0,
118
+ }
119
+
120
+ async def _ensure_services(self):
121
+ """Ensure required services are initialized."""
122
+ # Initialize Raft node if needed
123
+ if self.raft_node is None:
124
+ if self.node_id in self.group["raft_nodes"]:
125
+ self.raft_node = self.group["raft_nodes"][self.node_id]
126
+ else:
127
+ self.raft_node = RaftNode(self.node_id, self.peers or [])
128
+ self.group["raft_nodes"][self.node_id] = self.raft_node
129
+ await self.raft_node.start()
130
+
131
+ # Initialize leader election service
132
+ if self.leader_election is None:
133
+ if self.group["leader_election"] is None:
134
+ self.group["leader_election"] = EdgeLeaderElection(
135
+ self.group["raft_nodes"]
136
+ )
137
+ self.leader_election = self.group["leader_election"]
138
+
139
+ # Initialize ordering service
140
+ if self.ordering_service is None:
141
+ if self.group["ordering_service"] is None:
142
+ self.group["ordering_service"] = GlobalOrderingService(self.node_id)
143
+ self.ordering_service = self.group["ordering_service"]
144
+
145
+ async def async_run(self, **kwargs) -> Dict[str, Any]:
146
+ """Execute coordination operation."""
147
+ await self._ensure_services()
148
+
149
+ operation = kwargs.get("operation")
150
+
151
+ try:
152
+ if operation == "elect_leader":
153
+ return await self._handle_elect_leader(kwargs)
154
+ elif operation == "get_leader":
155
+ return await self._handle_get_leader(kwargs)
156
+ elif operation == "propose":
157
+ return await self._handle_propose(kwargs)
158
+ elif operation == "global_order":
159
+ return await self._handle_global_order(kwargs)
160
+ else:
161
+ self.metrics["errors"] += 1
162
+ return {"success": False, "error": f"Unknown operation: {operation}"}
163
+ except Exception as e:
164
+ self.logger.error(f"Coordination operation failed: {e}")
165
+ self.metrics["errors"] += 1
166
+ return {"success": False, "error": str(e)}
167
+
168
+ async def _handle_elect_leader(self, params: Dict[str, Any]) -> Dict[str, Any]:
169
+ """Handle leader election operation."""
170
+ self.metrics["elections_started"] += 1
171
+
172
+ result = await self.leader_election.start_election()
173
+
174
+ return {
175
+ "success": True,
176
+ "leader": result["leader"],
177
+ "term": result["term"],
178
+ "timestamp": datetime.now().isoformat(),
179
+ }
180
+
181
+ async def _handle_get_leader(self, params: Dict[str, Any]) -> Dict[str, Any]:
182
+ """Handle get current leader operation."""
183
+ leader_info = self.leader_election.get_current_leader()
184
+
185
+ return {
186
+ "success": True,
187
+ "leader": leader_info["leader"],
188
+ "term": leader_info["term"],
189
+ "stable": leader_info["stable"],
190
+ "timestamp": datetime.now().isoformat(),
191
+ }
192
+
193
+ async def _handle_propose(self, params: Dict[str, Any]) -> Dict[str, Any]:
194
+ """Handle consensus proposal operation."""
195
+ proposal = params.get("proposal")
196
+ if not proposal:
197
+ return {
198
+ "success": False,
199
+ "error": "Proposal required for propose operation",
200
+ }
201
+
202
+ # Check if we have a leader
203
+ leader_info = self.leader_election.get_current_leader()
204
+ if not leader_info["leader"]:
205
+ return {
206
+ "success": False,
207
+ "error": "No leader elected - cannot process proposal",
208
+ }
209
+
210
+ self.metrics["consensus_proposals"] += 1
211
+
212
+ # Submit proposal through Raft
213
+ result = await self.raft_node.propose(proposal)
214
+
215
+ return {
216
+ "success": result["success"],
217
+ "accepted": result["success"],
218
+ "log_index": result.get("index"),
219
+ "term": result.get("term"),
220
+ "error": result.get("error"),
221
+ "timestamp": datetime.now().isoformat(),
222
+ }
223
+
224
+ async def _handle_global_order(self, params: Dict[str, Any]) -> Dict[str, Any]:
225
+ """Handle global ordering operation."""
226
+ events = params.get("events", [])
227
+
228
+ self.metrics["ordering_requests"] += 1
229
+
230
+ # Order events
231
+ result = await self.ordering_service.order_events(events)
232
+
233
+ return {
234
+ "success": True,
235
+ "ordered_events": result["ordered_events"],
236
+ "logical_clock": result["logical_clock"],
237
+ "causal_dependencies": result.get("causal_dependencies", {}),
238
+ "timestamp": datetime.now().isoformat(),
239
+ }