Gemini CLI
Update MeshScale controller bundle
60539ea
Raw
History Blame Contribute Delete
5.76 kB
from __future__ import annotations
import os
import threading
import time
import traceback
from typing import Any
from fastapi import FastAPI
from key_farm.contracts import FarmPolicy
from key_farm.store import FarmStore
from key_farm.worker import worker_loop
app = FastAPI(title="MeshScale CPU Worker")
_worker_thread: threading.Thread | None = None
_supervisor_thread: threading.Thread | None = None
_worker_error: str | None = None
_worker_lock = threading.Lock()
def _int_env(name: str, default: int) -> int:
try:
return int(os.environ.get(name, str(default)))
except ValueError:
return default
def _float_env(name: str, default: float) -> float:
try:
return float(os.environ.get(name, str(default)))
except ValueError:
return default
def _bool_env(name: str, default: bool) -> bool:
raw = os.environ.get(name)
if raw is None:
return default
return raw.strip().lower() not in {"0", "false", "no", "off"}
def _root() -> str:
return os.environ.get("KEY_FARM_ROOT", "/data/farm")
def _formation() -> str:
return os.environ.get("KEY_FARM_FORMATION", "cpu-worker")
def _worker_id() -> str:
base = os.environ.get("KEY_FARM_WORKER_ID") or os.environ.get("SPACE_ID") or "meshscale-worker"
runtime = (
os.environ.get("SPACE_REPLICA_ID")
or os.environ.get("REPLICA_ID")
or os.environ.get("HOSTNAME")
or str(os.getpid())
)
return f"{base}:{runtime}"
def _policy() -> FarmPolicy:
formation = _formation()
return FarmPolicy(
target_batch_size=_int_env("KEY_FARM_TARGET_BATCH_SIZE", 24),
min_batch_size=_int_env("KEY_FARM_MIN_BATCH_SIZE", 4),
max_depth=_int_env("KEY_FARM_MAX_DEPTH", 4),
max_workers=_int_env("KEY_FARM_MAX_WORKERS", 24),
claim_ttl_seconds=_int_env("KEY_FARM_CLAIM_TTL_SECONDS", 900),
pulse_ttl_seconds=_int_env("KEY_FARM_PULSE_TTL_SECONDS", 120),
controller_pulse_ttl_seconds=_int_env("KEY_FARM_CONTROLLER_PULSE_TTL_SECONDS", 180),
budget_hourly_usd=_float_env("KEY_FARM_BUDGET_HOURLY_USD", 0.72),
cpu_space_hourly_usd=_float_env("KEY_FARM_CPU_SPACE_HOURLY_USD", 0.03),
exit_when_pulse_lost=_bool_env("KEY_FARM_EXIT_WHEN_PULSE_LOST", True),
pulse_rate=_float_env("KEY_FARM_PULSE_RATE", 1.0),
allowed_formations=(formation,),
)
def _run_worker() -> None:
global _worker_error
try:
worker_loop(
FarmStore(_root()),
_worker_id(),
_policy(),
poll_seconds=_float_env("KEY_FARM_POLL_SECONDS", 2.0),
once=False,
)
except Exception:
_worker_error = traceback.format_exc()
def _autostart_enabled() -> bool:
return _bool_env("MESHSCALE_WORKER_AUTOSTART", True)
def _controller_ready(store: FarmStore | None = None, policy: FarmPolicy | None = None) -> bool:
if not _bool_env("MESHSCALE_WORKER_WAIT_FOR_CONTROLLER", True):
return True
store = store or FarmStore(_root())
policy = policy or _policy()
return store.controller_pulse_alive(policy.controller_pulse_ttl_seconds)
def _start_worker_if_ready() -> bool:
global _worker_thread, _worker_error
if not _autostart_enabled():
return False
if _worker_error and not _bool_env("MESHSCALE_WORKER_RESTART_ON_ERROR", False):
return False
store = FarmStore(_root())
policy = _policy()
if not _controller_ready(store, policy):
return False
with _worker_lock:
if _worker_thread and _worker_thread.is_alive():
return True
_worker_error = None
_worker_thread = threading.Thread(target=_run_worker, name="meshscale-worker", daemon=True)
_worker_thread.start()
return True
def _supervise_worker() -> None:
while _autostart_enabled():
_start_worker_if_ready()
time.sleep(_float_env("MESHSCALE_WORKER_SUPERVISOR_SECONDS", 5.0))
def _ensure_supervisor_started() -> None:
global _supervisor_thread
if not _autostart_enabled():
return
if _supervisor_thread and _supervisor_thread.is_alive():
return
_supervisor_thread = threading.Thread(
target=_supervise_worker,
name="meshscale-worker-supervisor",
daemon=True,
)
_supervisor_thread.start()
def _ensure_worker_started() -> None:
if not _bool_env("MESHSCALE_WORKER_AUTOSTART", True):
return
_ensure_supervisor_started()
_start_worker_if_ready()
@app.on_event("startup")
def startup() -> None:
_ensure_worker_started()
@app.get("/health")
def health() -> dict[str, Any]:
store = FarmStore(_root())
policy = _policy()
_ensure_worker_started()
return {
"ok": _worker_error is None,
"worker_id": _worker_id(),
"formation": _formation(),
"thread_alive": bool(_worker_thread and _worker_thread.is_alive()),
"supervisor_alive": bool(_supervisor_thread and _supervisor_thread.is_alive()),
"root": str(store.root),
"controller_alive": store.controller_pulse_alive(policy.controller_pulse_ttl_seconds),
"regulation": store.read_regulation().to_dict(),
"error": _worker_error,
}
@app.get("/state")
def state() -> dict[str, Any]:
store = FarmStore(_root())
policy = _policy()
_ensure_worker_started()
return {
"worker_id": _worker_id(),
"formation": _formation(),
"pending_jobs": len(store.pending_jobs(_formation())),
"active_workers": store.active_worker_count(policy.pulse_ttl_seconds, _formation()),
"controller_alive": store.controller_pulse_alive(policy.controller_pulse_ttl_seconds),
"policy": policy.to_dict(),
}