Skip to content

Replace orchestrator pools with a single takeover RPC - #489

Closed
hermabr wants to merge 1 commit into
mainfrom
takeover-single-rpc
Closed

Replace orchestrator pools with a single takeover RPC#489
hermabr wants to merge 1 commit into
mainfrom
takeover-single-rpc

Conversation

@hermabr

@hermabr hermabr commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Minimal rework of the orchestrator-takeover design (supersedes the two-message inventory/claim version). A new run started with FURU_REPLACE_ORCHESTRATOR inherits a live run's Slurm workers instead of re-queueing them.

Design: one RPC, each side does its own local work

The successor prepares its snapshot, venv, and worker config before connecting — that's the same work a cold start needs, so nothing is wasted if the takeover matches nothing. It then sends one /takeover request: its coordinates, one offer per Slurm backend. The old coordinator does everything local to it:

  1. matches offers to its pools by fingerprint,
  2. stops scaling and rewrites the matched pools' endpoint files to the offered coordinates,
  3. signals its running workers with scancel --signal=USR1,
  4. answers with the adopted pools' job ids and shuts itself down.

The successor never touches another run's files or Slurm jobs. Besides being smaller (two wire models instead of six, no mid-handshake state where the successor holds half-finished writes into someone else's directory, no separate "drop before claim" path), this is the division of labor a multi-cluster future needs: only the side that owns a cluster has filesystem and scancel access to it, so "redirect yourself to me" is the message shape that survives, even though nothing multi-cluster is built here.

Worker-side machinery is unchanged from the previous design: sbatch scripts resolve the coordinator URL, token, project, and config through a per-pool endpoint file at runtime, and a disconnected worker re-reads the file and re-execs when the generation grew. The filesystem live-run registry remains as a dumb discovery pointer ({url, token}).

Failure behavior

  • A takeover that matches nothing changes nothing: the old run only surrenders and stops after adopting at least one pool, and the destructive step is gated on a fully validated request.
  • A dropped or malformed connection before the request surrenders nothing.
  • A worker that misses the USR1 signal still redirects at its next touch of the dead old socket.

Note: tests/test_furu_locking_contention.py::test_lock_is_taken_over_mid_create is flaky on slow filesystems (0.5s spawn deadline) — it fails identically on unmodified main on my machine and is unrelated.

🤖 Generated with Claude Code

A new run started with FURU_REPLACE_ORCHESTRATOR inherits a live run's
Slurm workers instead of re-queueing them. The successor prepares its
snapshot, venv, and worker config up front (the same work a cold start
needs), then sends the old coordinator one /takeover request carrying
its coordinates — one offer per Slurm backend. The old run does all the
local work itself: it matches offers to its pools by fingerprint,
rewrites the matched endpoint files, signals its running workers with
SIGUSR1, and only then answers and shuts down. The successor never
touches another run's files or Slurm jobs, which is also the shape a
future multi-cluster setup needs, where only the old side has
filesystem and scancel access to its cluster.

Workers stay redirectable because their sbatch scripts resolve the
coordinator URL, auth token, project, and config through a per-pool
endpoint file at runtime; a worker that disconnects re-reads the file
and re-execs into the new project when the generation grew.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hermabr hermabr closed this Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant