55 lines
1.1 KiB
Python
55 lines
1.1 KiB
Python
from dataclasses import dataclass, field
|
|
from typing import Dict, Any, Optional
|
|
|
|
|
|
@dataclass
|
|
class NodeState:
|
|
"""
|
|
Single source of truth for node health + capability.
|
|
"""
|
|
|
|
name: str
|
|
|
|
# runtime
|
|
cpu_load: float = 0.0
|
|
memory_load: float = 0.0
|
|
temp: float = 0.0
|
|
|
|
# scheduling intelligence
|
|
score: float = 0.0
|
|
instability: float = 0.0
|
|
|
|
# execution tracking
|
|
active_jobs: int = 0
|
|
last_seen: float = 0.0
|
|
|
|
# capabilities
|
|
labels: Dict[str, Any] = field(default_factory=dict)
|
|
|
|
# health flags
|
|
healthy: bool = True
|
|
degraded: bool = False
|
|
offline: bool = False
|
|
|
|
|
|
class NodeStateRegistry:
|
|
"""
|
|
Central authority for node truth.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.nodes: Dict[str, NodeState] = {}
|
|
|
|
def update(self, name: str, **kwargs):
|
|
if name not in self.nodes:
|
|
self.nodes[name] = NodeState(name=name)
|
|
|
|
for k, v in kwargs.items():
|
|
setattr(self.nodes[name], k, v)
|
|
|
|
def get(self, name: str) -> Optional[NodeState]:
|
|
return self.nodes.get(name)
|
|
|
|
def all(self):
|
|
return list(self.nodes.values())
|