Skip to content

FIX: log and retry supervisor connection during worker startup - #5278

Open
OliverBryant wants to merge 1 commit into
xorbitsai:mainfrom
OliverBryant:fix/worker-startup-supervisor-connect
Open

FIX: log and retry supervisor connection during worker startup#5278
OliverBryant wants to merge 1 commit into
xorbitsai:mainfrom
OliverBryant:fix/worker-startup-supervisor-connect

Conversation

@OliverBryant

Copy link
Copy Markdown
Collaborator

What does this PR do?

Fixes #5268.

A starting worker's first network operation is a REST call to the supervisor (RESTfulClient.__init__ -> /v1/cluster/auth, then /v1/address), performed before any first-party log line is emitted, with no timeout and no retry. When the supervisor endpoint is unreachable, the worker process dies (or hangs) showing nothing but third-party import noise, e.g.:

Failed to load .../torchao/_C_cutlass_90a.abi3.so: ...
W0801 11:05:03 ... torch/utils/_pytree.py:630 ...

With restart: always in docker compose this becomes a silent crash loop, which is exactly the log signature reported in #5268 (repeated torchao import noise, no worker logs). I reproduced both directions on the v3.1.0-cpu image:

  • Clean environment (supervisor reachable): worker starts normally, so the image itself is fine.
  • Unreachable / refused endpoint: worker crashes before its first log line, then restart-loops.

Changes

  • xinference/deploy/cmdline.py: log the supervisor endpoint immediately after logging is configured, and resolve the supervisor internal address through a retry loop (5s interval, up to 5 minutes) with explicit warnings carrying the endpoint, the error, and the attempt count. Workers now survive the common "supervisor not up yet" race and join automatically once it becomes reachable; after the retry budget is exhausted the original exception is re-raised with an actionable error message.
  • xinference/client/restful/restful_client.py: bound the /v1/cluster/auth and /v1/address metadata GETs with a (10, 30) connect/read timeout so an endpoint that accepts TCP but never responds cannot hang client construction indefinitely. Inference requests are deliberately left untouched.
  • xinference/deploy/test/test_cmdline.py: tests covering retry-then-success and retry-exhaustion.

Verification

  • pytest xinference/deploy/test/test_cmdline.py -k worker_command (3 passed).
  • pre-commit run on the modified files (all hooks passed).
  • End-to-end on the v3.1.0-cpu Docker image with the patched files mounted in:
    • worker pointed at a dead endpoint now logs Starting Xinference worker. Supervisor endpoint: ... followed by Supervisor at ... is not ready (ConnectionError: ...), retrying in 5 seconds (attempt 1/60) instead of dying silently;
    • starting the supervisor while the worker was retrying resulted in the worker connecting and reaching Xinference worker ... started without a container restart.

Not run: full CI-style test suite (model tests require GPU/network); left to CI.

A starting worker's first network operation is a REST call to the
supervisor made before any log line is emitted, with no timeout and no
retry. When the supervisor endpoint is unreachable the worker dies (or
hangs) showing nothing but third-party import noise, and with Docker's
restart policy this becomes a silent crash loop that is very hard to
diagnose.

- Log the supervisor endpoint right after logging is configured so a
  worker always produces a first-party startup line.
- Retry the supervisor address resolution with explicit warnings
  (attempt count, endpoint, error) for up to 5 minutes, so workers
  survive supervisor-not-yet-up races in docker compose deployments
  and join automatically once the supervisor is reachable.
- Bound the /v1/cluster/auth and /v1/address metadata requests with a
  (10, 30) timeout so an unresponsive endpoint cannot hang the client
  construction indefinitely.
@XprobeBot XprobeBot added the bug Something isn't working label Aug 4, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@XprobeBot XprobeBot added the gpu label Aug 4, 2026
@XprobeBot XprobeBot added this to the v3.x milestone Aug 4, 2026
@OliverBryant OliverBryant mentioned this pull request Aug 4, 2026
3 tasks
@OliverBryant OliverBryant self-assigned this Aug 4, 2026
max_attempts = _SUPERVISOR_CONNECT_MAX_ATTEMPTS
if retry_interval is None:
retry_interval = _SUPERVISOR_CONNECT_RETRY_INTERVAL
for attempt in range(1, max_attempts + 1):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Enforce the retry budget by elapsed time

The advertised five-minute limit currently counts only the retry sleeps. Each attempt can additionally spend up to 30 seconds in the metadata request, so an endpoint that accepts TCP but never responds can keep the worker here for roughly 35 minutes instead of five. This is one of the failure modes this change is intended to bound. Please use a monotonic wall-clock deadline (or otherwise include request duration in the total budget) and add a regression test with slow failed attempts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working gpu

Projects

None yet

Development

Successfully merging this pull request may close these issues.

worker-cpu cannot startup

3 participants