Skip to content

fix(lb): retry targets rejected because the balancer is busy - #59

Merged
s3rius merged 1 commit into
perf/watch-cluster-changesfrom
fix/retry-busy-balancer
Oct 13, 2026
Merged

s3rius merged 1 commit into
perf/watch-cluster-changesfrom
fix/retry-busy-balancer

Conversation

@lexfrei

@lexfrei lexfrei commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

A target added while another action is still running on the balancer gets skipped as if the IP were invalid (#54). Hetzner answers 423 locked in that window.

The add-target loop now retries a temporary rejection (locked, conflict, robot_unavailable or a 5xx) twice, after 1s and 2s. A permanent one, like an IP outside the vSwitch subnet, is skipped as before. A 429 is still returned at once for the rate limit gate. After one target has used up its retries, the other targets in that run are not retried, because the lock is on the whole balancer.

I did not add waiting for the running action to finish. That costs extra API calls per target, and the retry plus the existing 30 second requeue covers the short window. Other balancer calls (removing targets, changing services) still fail on locked as before.

tokio::time relies on the tokio time feature; #52 declares it explicitly.

Stacked on #49.

Closes #54

@s3rius s3rius left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure if we even need retries, because kubernetes handles reconcilidation itself.

So in any case the retry will happen on kubernetes side. Maybe we don't need this PR, it adds functionality that already exists but on a platform level.

Comment thread src/lb.rs
pando85 added a commit to forkline/robotlb that referenced this pull request Oct 13, 2026
Retry 409/423/5xx and robot_unavailable responses on target updates,
balancer type and algorithm changes with 1s/2s delay. Treat a target
already added by a previous attempt as success. 429 stays governed
by the shared rate-limit gate.

Ported-from: Treetscom#59
Related-to: Treetscom#66
@s3rius
s3rius added this pull request to stack #80 October 13, 2026 08:43
Hetzner answers 423 locked while an action is still running on the
balancer, and the operator skipped the target on that answer as if it
were permanently invalid. A node added right after another change could
stay out of the balancer until the next reconcile.

Tell temporary rejections (locked, conflict, robot_unavailable, 5xx)
from permanent ones and retry the former up to twice, after 1s and 2s.
A target that still fails is skipped as before, and a 429 is still
returned at once for the rate limit gate. Once one target has used up
its retries, the rest of the run does not retry: the lock is on the
whole balancer, and waiting per target would stall the service for
minutes on a large balancer.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@s3rius
s3rius force-pushed the fix/retry-busy-balancer branch from 128fd31 to 2e700c5 Compare October 13, 2026 10:13
@s3rius
s3rius merged commit 5fada68 into master Oct 13, 2026
1 check passed
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.

Adding targets does not wait for the balancer's running action

2 participants