58 lines
1.5 KiB
Python
Executable File
58 lines
1.5 KiB
Python
Executable File
"""Legacy scheduler scoring — kept for backward compatibility.
|
|
|
|
Re-exported by :mod:`backend.scheduler` so existing callers
|
|
(``from backend.scheduler import score_node, build_distcc_hosts``)
|
|
keep working.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Any, List, Mapping
|
|
|
|
from backend.governor import thermal_cap
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def score_node(node: Mapping[str, Any]) -> float:
|
|
"""Return a 0..N scheduling score for ``node`` (higher = better)."""
|
|
if node["state"] == "offline":
|
|
return 0.0
|
|
|
|
agent = node.get("agent") or {}
|
|
|
|
try:
|
|
load = float(str(agent.get("load", "1 1 1")).split()[0])
|
|
except (ValueError, IndexError, AttributeError):
|
|
log.debug("could not parse load=%r from node %s; falling back to 1.0",
|
|
agent.get("load"), node.get("name"))
|
|
load = 1.0
|
|
|
|
base = 10.0
|
|
capacity = node.get("max_jobs", 8)
|
|
|
|
score = (base + capacity) - (load * 3.0)
|
|
|
|
return max(score, 0.1) * thermal_cap(agent)
|
|
|
|
|
|
def build_distcc_hosts(nodes: List[Mapping[str, Any]]) -> str:
|
|
"""Build a ``DISTCC_HOSTS`` string weighted by :func:`score_node`."""
|
|
scored = [(n, score_node(n)) for n in nodes]
|
|
|
|
total = sum(s for _, s in scored) or 1.0
|
|
|
|
hosts: List[str] = []
|
|
|
|
for node, score in scored:
|
|
if node["state"] == "offline":
|
|
continue
|
|
|
|
weight = int((score / total) * 64)
|
|
weight = max(1, weight)
|
|
|
|
hosts.append(f"{node['host']}/{weight}")
|
|
|
|
return " ".join(hosts)
|