deploy controller (cd97485)
Browse files
README.md
CHANGED
|
@@ -8,6 +8,6 @@ app_port: 7860
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
-
swarm-harness controller (
|
| 12 |
https://github.com/huggingface/swarm-harness. The API needs the swarm bearer token;
|
| 13 |
`/` (status table) and `/healthz` are open.
|
|
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
+
swarm-harness controller (cd97485). Source:
|
| 12 |
https://github.com/huggingface/swarm-harness. The API needs the swarm bearer token;
|
| 13 |
`/` (status table) and `/healthz` are open.
|
src/swarm_harness/controller/reconcile.py
CHANGED
|
@@ -365,6 +365,7 @@ def _launch(p: _Pass, spec: SwarmSpec, type_name: str, ts: TypeSpec, w: Row) ->
|
|
| 365 |
"SWARM": spec.swarm,
|
| 366 |
"TYPE": type_name,
|
| 367 |
"DEADLINE": _iso(deadline),
|
|
|
|
| 368 |
"BUCKET": spec.bucket,
|
| 369 |
}
|
| 370 |
secrets = {"SWARM_HARNESS_TOKEN": s.token}
|
|
|
|
| 365 |
"SWARM": spec.swarm,
|
| 366 |
"TYPE": type_name,
|
| 367 |
"DEADLINE": _iso(deadline),
|
| 368 |
+
"DRAIN_WINDOW": ts.drain_window, # known before the first assign arrives
|
| 369 |
"BUCKET": spec.bucket,
|
| 370 |
}
|
| 371 |
secrets = {"SWARM_HARNESS_TOKEN": s.token}
|
src/swarm_harness/worker/main.py
CHANGED
|
@@ -63,6 +63,7 @@ class WorkerConfig:
|
|
| 63 |
heartbeat_interval: float = HEARTBEAT_INTERVAL.total_seconds()
|
| 64 |
flush_interval: float = 3.0
|
| 65 |
sync_interval: float = 180.0
|
|
|
|
| 66 |
|
| 67 |
@classmethod
|
| 68 |
def from_env(cls, env: Mapping[str, str] = os.environ) -> WorkerConfig:
|
|
@@ -77,6 +78,7 @@ class WorkerConfig:
|
|
| 77 |
work_root=Path(env.get("WORK_ROOT", "/work/agents")),
|
| 78 |
sync_interval=float(env.get("SYNC_INTERVAL", 180)),
|
| 79 |
heartbeat_interval=float(env.get("HEARTBEAT_INTERVAL", HEARTBEAT_INTERVAL.total_seconds())),
|
|
|
|
| 80 |
)
|
| 81 |
|
| 82 |
|
|
@@ -148,7 +150,7 @@ class Worker:
|
|
| 148 |
self.outbox = Outbox()
|
| 149 |
self.agents: dict[str, AgentRuntime] = {}
|
| 150 |
self.draining = False
|
| 151 |
-
self.drain_window =
|
| 152 |
self._drained = asyncio.Event()
|
| 153 |
self._tasks: set[asyncio.Task] = set()
|
| 154 |
self._wake_heartbeat = asyncio.Event()
|
|
@@ -334,16 +336,11 @@ class Worker:
|
|
| 334 |
|
| 335 |
|
| 336 |
def quiet_libraries() -> None:
|
| 337 |
-
"""One line per poll/heartbeat and tqdm bars per upload would drown the job log.
|
|
|
|
| 338 |
for name in ("httpx", "httpx2", "httpcore"):
|
| 339 |
logging.getLogger(name).setLevel(logging.WARNING)
|
| 340 |
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
|
| 341 |
-
try:
|
| 342 |
-
from huggingface_hub.utils import disable_progress_bars
|
| 343 |
-
|
| 344 |
-
disable_progress_bars()
|
| 345 |
-
except ImportError:
|
| 346 |
-
pass
|
| 347 |
|
| 348 |
|
| 349 |
def main() -> None:
|
|
|
|
| 63 |
heartbeat_interval: float = HEARTBEAT_INTERVAL.total_seconds()
|
| 64 |
flush_interval: float = 3.0
|
| 65 |
sync_interval: float = 180.0
|
| 66 |
+
drain_window: timedelta = DEFAULT_DRAIN_WINDOW # from the job env; assigns may update it
|
| 67 |
|
| 68 |
@classmethod
|
| 69 |
def from_env(cls, env: Mapping[str, str] = os.environ) -> WorkerConfig:
|
|
|
|
| 78 |
work_root=Path(env.get("WORK_ROOT", "/work/agents")),
|
| 79 |
sync_interval=float(env.get("SYNC_INTERVAL", 180)),
|
| 80 |
heartbeat_interval=float(env.get("HEARTBEAT_INTERVAL", HEARTBEAT_INTERVAL.total_seconds())),
|
| 81 |
+
drain_window=parse_duration(env.get("DRAIN_WINDOW") or DEFAULT_DRAIN_WINDOW),
|
| 82 |
)
|
| 83 |
|
| 84 |
|
|
|
|
| 150 |
self.outbox = Outbox()
|
| 151 |
self.agents: dict[str, AgentRuntime] = {}
|
| 152 |
self.draining = False
|
| 153 |
+
self.drain_window = cfg.drain_window
|
| 154 |
self._drained = asyncio.Event()
|
| 155 |
self._tasks: set[asyncio.Task] = set()
|
| 156 |
self._wake_heartbeat = asyncio.Event()
|
|
|
|
| 336 |
|
| 337 |
|
| 338 |
def quiet_libraries() -> None:
|
| 339 |
+
"""One line per poll/heartbeat and tqdm bars per upload would drown the job log. The env var
|
| 340 |
+
(read by huggingface_hub and its xet uploads) works where disable_progress_bars() does not."""
|
| 341 |
for name in ("httpx", "httpx2", "httpcore"):
|
| 342 |
logging.getLogger(name).setLevel(logging.WARNING)
|
| 343 |
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
|
| 345 |
|
| 346 |
def main() -> None:
|