48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
"""CPU sampling helpers for Nexus Agent heartbeats."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import psutil
|
|
|
|
_primed = False
|
|
_watch_bootstrapped = False
|
|
|
|
|
|
def reset_watch_cpu_bootstrap() -> None:
|
|
"""Call when entering watch mode so first sample uses a 1s blocking window."""
|
|
global _watch_bootstrapped
|
|
_watch_bootstrapped = False
|
|
|
|
|
|
def _prime_nonblocking() -> None:
|
|
global _primed
|
|
if not _primed:
|
|
psutil.cpu_percent(interval=None)
|
|
_primed = True
|
|
|
|
|
|
def sample_cpu_percent(*, watch_mode: bool) -> float:
|
|
"""Idle heartbeats: CPU since last sample (up to ~60s). Watch: ~5s window after bootstrap."""
|
|
_prime_nonblocking()
|
|
if watch_mode:
|
|
global _watch_bootstrapped
|
|
if not _watch_bootstrapped:
|
|
_watch_bootstrapped = True
|
|
return round(float(psutil.cpu_percent(interval=1.0)), 1)
|
|
return round(float(psutil.cpu_percent(interval=None)), 1)
|
|
return round(float(psutil.cpu_percent(interval=None)), 1)
|
|
|
|
|
|
def sample_watch_cpu_bundle() -> tuple[float, list[float]]:
|
|
"""Watch-mode overall + per-core; interval=None measures since prior heartbeat (~5s)."""
|
|
_prime_nonblocking()
|
|
global _watch_bootstrapped
|
|
if not _watch_bootstrapped:
|
|
_watch_bootstrapped = True
|
|
per = psutil.cpu_percent(interval=1.0, percpu=True)
|
|
else:
|
|
per = psutil.cpu_percent(interval=None, percpu=True)
|
|
per_list = [round(float(x), 1) for x in per]
|
|
overall = round(sum(per_list) / len(per_list), 1) if per_list else 0.0
|
|
return overall, per_list
|