Skip to content

fix: bound backend dial with a timeout so asleep MOTD is served promptly#569

Merged
itzg merged 1 commit into
itzg:mainfrom
CODECRAFTCLOUD:fix/backend-dial-timeout
Jul 12, 2026
Merged

fix: bound backend dial with a timeout so asleep MOTD is served promptly#569
itzg merged 1 commit into
itzg:mainfrom
CODECRAFTCLOUD:fix/backend-dial-timeout

Conversation

@wachirachoomsiri

Copy link
Copy Markdown
Contributor

Problem

With --auto-scale-up, when a backend's StatefulSet is scaled to 0 its ClusterIP Service has no endpoints. net.Dial("tcp", backendHostPort) on that address hangs on the OS SYN-retry timeout (~30s) instead of failing fast.

The auto-scale asleep MOTD is only served from the dial-failure fallback in findAndConnectBackend. Because the dial hangs ~30s, a client's server-list ping usually gives up before the fallback runs — so the asleep MOTD "shows only sometimes".

Fix

Bound the backend dial with net.DialTimeout (2s). A healthy backend accepts the TCP connection almost instantly, so this only trips on unreachable/asleep backends — letting the existing status fallback serve the asleep MOTD promptly.

Evidence

Verified on a live Kubernetes cluster: asleep MOTD went from ~30s (usually a client timeout, MOTD never shown) to ~2s.

Note

The 2s bound is a const (backendDialTimeout) — happy to make it a flag if you'd prefer that over a fixed value.

🤖 Generated with Claude Code

Dialing a Service whose StatefulSet is scaled to 0 hangs on the OS SYN-retry
timeout (~30s) because the ClusterIP has no endpoints. The auto-scale asleep
MOTD is only served from the dial-failure fallback, so the client's server-list
ping times out before the MOTD arrives (MOTD "shows only sometimes").

Bound the dial with net.DialTimeout. A healthy backend accepts the TCP
connection almost instantly, so this only trips on unreachable/asleep backends,
letting the existing status fallback serve the asleep MOTD promptly. Verified on
a live cluster: asleep MOTD went from ~30s (usually a client timeout) to ~2s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@itzg itzg left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks!

@itzg
itzg merged commit 97b15df into itzg:main Jul 12, 2026
1 of 2 checks passed
@itzg itzg added the bug Something isn't working label Jul 12, 2026
wachirachoomsiri added a commit to CODECRAFTCLOUD/mc-router that referenced this pull request Jul 12, 2026
Dial-timeout (itzg#569) is now upstream, so this reconciles history. uniz keeps
its configurable --backend-dial-timeout (PR itzg#570 pending) and wake-ux patches;
no file changes result (uniz already contains all upstream content).
itzg pushed a commit that referenced this pull request Jul 13, 2026
…out) (#570)

Follow-up to #569: replace the fixed 2s backendDialTimeout constant with a --backend-dial-timeout flag (env BACKEND_DIAL_TIMEOUT), defaulting to the same 2s. Operators whose backends are reachable quickly (e.g. on-cluster Kubernetes Services) can lower it so the asleep MOTD / scale-up fallback fires sooner on a scaled-to-zero backend.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@itzg

itzg commented Jul 19, 2026

Copy link
Copy Markdown
Owner

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants