from metrics.target_scoring import TargetScorer from metrics.target_labeler import TargetLabeler from metrics.profile_store import save class LiveTargetState: def __init__(self, target_key): self.target = target_key # ----------------------------- # RUNNING STATE (incremental) # ----------------------------- self.cpu_sum = 0 self.temp_sum = 0 self.samples = 0 self.peak_temp = 0 self.actions = 0 self.cache_hits = 0 self.failures = 0 # ----------------------------- # CACHED DERIVED VALUES # ----------------------------- self.cached_score = None self.cached_labels = None self.dirty = True class FesterIntelligence: def __init__(self): self.states = {} self.scorer = TargetScorer() self.labeler = TargetLabeler() # ----------------------------- # INIT # ----------------------------- def start_target(self, target_key): self.states[target_key] = LiveTargetState(target_key) # ----------------------------- # FAST UPDATES (O(1)) # ----------------------------- def sample(self, target_key, node): s = self.states[target_key] cpu = node.get("cpu_load", 0) temp = node.get("temp", 0) s.cpu_sum += cpu s.temp_sum += temp s.samples += 1 if temp > s.peak_temp: s.peak_temp = temp s.dirty = True def record_event(self, target_key, event): s = self.states[target_key] if event == "action": s.actions += 1 elif event == "cache_hit": s.cache_hits += 1 elif event == "failure": s.failures += 1 s.dirty = True # ----------------------------- # FAST SNAPSHOT (NO RECOMPUTE UNLESS DIRTY) # ----------------------------- def snapshot(self, target_key): s = self.states.get(target_key) if not s: return None # ----------------------------- # RETURN CACHED RESULT # ----------------------------- if not s.dirty and s.cached_score is not None: return { "score": s.cached_score, "labels": s.cached_labels } # ----------------------------- # COMPUTE AGGREGATES # ----------------------------- avg_cpu = s.cpu_sum / s.samples if s.samples else 0 avg_temp = s.temp_sum / s.samples if s.samples else 0 cache_ratio = s.cache_hits / s.actions if s.actions else 0 profile = { "duration": 0, # intentionally not scheduler-relevant anymore "avg_cpu": avg_cpu, "avg_temp": avg_temp, "peak_temp": s.peak_temp, "cache_ratio": cache_ratio, "failures": s.failures } score = self.scorer.score(profile) labels = self.labeler.label(score) # ----------------------------- # CACHE RESULT # ----------------------------- s.cached_score = score s.cached_labels = labels s.dirty = False return { "score": score, "labels": labels } # ----------------------------- # FINALIZE (ARCHIVAL ONLY) # ----------------------------- def finalize(self, target_key): s = self.states[target_key] snapshot = self.snapshot(target_key) save({ "target": target_key, "score": snapshot["score"], "labels": snapshot["labels"] }) return snapshot