mirror of
https://github.com/blw1138/cross-py-builder.git
synced 2026-09-07 21:41:09 -05:00
Replace the CROSS_PY_WORKERS env list with a DB-backed worker store so agents can be added/removed (and their online status verified) from the browser. - db.py: add workers table + list_workers/add_worker/remove_worker. - workers.py: configured_workers() reads the DB instead of settings. - app.py: POST /api/workers (add, probes reachability) and DELETE /api/workers/<port>/<host>; startup log uses DB worker count. - UI: Workers card with add form, per-worker live status + OS/CPU, remove. - settings.py: drop CROSS_PY_WORKERS/_get_json_list; DB is single source. - README/DESIGN updated to describe UI-managed workers.
59 lines
1.7 KiB
Python
59 lines
1.7 KiB
Python
import ctrl.db as db
|
|
import ctrl.settings as settings
|
|
import requests
|
|
|
|
|
|
def parse_worker(spec):
|
|
"""'host:port' -> {'url': 'http://host:port', 'host': host, 'port': port}."""
|
|
host, _, port = spec.strip().rpartition(":")
|
|
if not host or not port.isdigit():
|
|
raise ValueError(f"Invalid worker spec: {spec!r} (expected host:port)")
|
|
return {"url": f"http://{host}:{port}", "host": host, "port": int(port)}
|
|
|
|
|
|
def configured_workers():
|
|
out = []
|
|
for w in db.list_workers():
|
|
out.append({
|
|
"url": f"http://{w['host']}:{w['port']}",
|
|
"host": w["host"],
|
|
"port": w["port"],
|
|
})
|
|
return out
|
|
|
|
|
|
def probe_worker(url, timeout=None):
|
|
"""Return a normalized worker status dict, or None if unreachable."""
|
|
timeout = timeout or settings.WORKER_STATUS_TIMEOUT
|
|
try:
|
|
resp = requests.get(f"{url}/status", timeout=timeout)
|
|
resp.raise_for_status()
|
|
info = resp.json()
|
|
except (requests.RequestException, ValueError):
|
|
return None
|
|
|
|
info["url"] = url
|
|
info["online"] = True
|
|
return info
|
|
|
|
|
|
def probe_all():
|
|
workers = []
|
|
for w in configured_workers():
|
|
status = probe_worker(w["url"])
|
|
if status:
|
|
workers.append(status)
|
|
else:
|
|
workers.append({"url": w["url"], "host": w["host"], "port": w["port"], "online": False})
|
|
return workers
|
|
|
|
|
|
def matches(job, worker):
|
|
if worker.get("status") != "ready":
|
|
return False
|
|
if job.get("os_req") and job["os_req"].lower() not in str(worker.get("os", "")).lower():
|
|
return False
|
|
if job.get("cpu_req") and job["cpu_req"].lower() not in str(worker.get("cpu", "")).lower():
|
|
return False
|
|
return True
|