From b9828fe7a63cbbbcae3e1380e24802c0bb9e8558 Mon Sep 17 00:00:00 2001 From: pradipta-lyzr Date: Tue, 4 Aug 2026 19:29:25 +0530 Subject: [PATCH] worker: honour backend_factory when reporting the machine's backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit run_worker read the backend name straight from select_backend("auto") before the job loop, so a worker started with an explicit backend_factory still insisted on resolving a real one — and raised "No training backend available" on any box without mlx or torch installed. That is precisely the case backend_factory exists to serve, and _run_job already honoured it; only registration didn't. This is why the two hub↔worker tests failed on main: they hand in a stub backend to exercise the real _Link and the real socket without a training stack, and never got past registration. They also cost 15 seconds each waiting on a thread that had already died, so the CPU suite drops from ~25s to ~5s. --- shadowlm/worker.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shadowlm/worker.py b/shadowlm/worker.py index e4e67e3..ae95bf1 100644 --- a/shadowlm/worker.py +++ b/shadowlm/worker.py @@ -329,7 +329,11 @@ def run_worker(hub: str | None = None, *, name: str | None = None, work_root = Path(work_root or Path.home() / ".shadowlm" / "worker") work_root.mkdir(parents=True, exist_ok=True) - be_name = select_backend("auto").name # what this machine trains with + # What this machine trains with. When a factory is supplied it *is* the + # backend — consulting select_backend anyway would raise on a box with no + # training stack installed, which is the one situation backend_factory + # exists for. _run_job already honours the override; this didn't. + be_name = (backend_factory() if backend_factory else select_backend("auto")).name link = _Link(client, name, { "backend": be_name, "device": f"{platform.system()}/{platform.machine()}",