Skip to content

worker: retry the connect+auth+registration handshake on transient stalls#1118

Open
MauriceDHanisch wants to merge 1 commit into
It4innovations:mainfrom
MauriceDHanisch:pr/worker-registration-retry
Open

worker: retry the connect+auth+registration handshake on transient stalls#1118
MauriceDHanisch wants to merge 1 commit into
It4innovations:mainfrom
MauriceDHanisch:pr/worker-registration-retry

Conversation

@MauriceDHanisch

Copy link
Copy Markdown

Summary

  • Extracts the worker's connect -> authenticate -> send registration -> await response sequence into connect_and_register, and wraps it in connect_and_register_with_retry (8 attempts, 10s backoff between attempts).
  • Adds DsError::AuthenticationRejected, a distinct, non-retryable error variant for deterministic auth rejections (wrong secret key, incompatible protocol/role, bad challenge, etc.), and updates finish_authentication's rejection sites in auth.rs to construct it explicitly instead of falling through the generic GenericError catch-all. The retry loop treats this variant as immediately fatal; every other error is retried.
  • Along the way, replaces two hard panic!s in the old inline registration-response-wait code with proper Err(...) returns.

Motivation

The raw TCP connect step already retried (20x/2s via connect_to_server), but nothing downstream of it did. On a busy server — mid MILP scheduler solve on its single-threaded executor, or handling a burst of other workers registering concurrently — any leg of the auth handshake or the registration round-trip could miss its own hardcoded 15s timeout simply because the server didn't get scheduled in time to answer, not because anything was actually wrong. That killed the whole hq worker start process outright. On an autoalloc-managed SLURM pilot, that means the entire allocation is wasted, not just one delayed worker.

Reproduced live with a combined registration-burst + real scheduler-load stress test: previously a second batch of workers was left permanently unable to register; with this change all of them (tested up to 30 workers) connect and register cleanly.

Client-side CLI RPCs (Connection::init in connection.rs) are a separate caller of do_authentication and are intentionally untouched — those should keep failing fast rather than retrying.

Test plan

  • cargo check -p hyperqueue -p tako
  • cargo test -p tako — 205 passed, 0 failed, ~5s (confirmed the three deterministic-auth-rejection tests in test_secret.rs stay fast — they hit the new non-retryable AuthenticationRejected path instead of looping through all 8 retry attempts)
  • Live stress repro: registration burst + real scheduler load, up to 30 workers, zero registration failures

…nt stalls

A busy server (mid MILP scheduler solve on its single-threaded executor, or
handling a burst of other workers registering) could fail to poll a new
worker's connection in time for any leg of the auth handshake or the
registration round-trip to complete within its own hardcoded 15s timeout.
None of those legs were retried (only the raw TCP connect already was), so
one slow attempt killed the whole hq worker start process -- on an
autoalloc-managed SLURM pilot, that means the entire allocation is wasted,
not just a delayed worker. Reproduced live: a combined registration-burst +
real scheduler-load stress test that previously left a second batch of
workers permanently unable to register now has all of them connect cleanly
(tested up to 30 workers).

Retries the whole connect+authenticate+register+await-response sequence
(connect_and_register_with_retry, 8 attempts / 10s backoff) rather than
raising the fixed 15s timeouts themselves, since there's no fixed stall
duration to size a bigger timeout against. Also fixes two latent panics on
the registration-response wait (a timeout or early connection close used to
abort the process outright instead of returning a proper error).

Added DsError::AuthenticationRejected, distinct from the existing transient
GenericError, so a deterministic rejection (wrong secret key, incompatible
protocol/role) fails fast instead of retrying 8 times for an outcome that
will never change -- caught by the existing test_secret.rs tests, which
went from ~0.1s to ~70s combined before this fix.

Scoped to the worker's own connection to the server only (worker/rpc.rs);
client CLI commands and server-side code are untouched.
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