checker: fix ResumeBackend leaking goroutine on non-paused backend; v1.0.2
Calling ResumeBackend on a backend that wasn't actually paused (state != StatePaused) would overwrite w.cancel and spawn a fresh probe goroutine without cancelling the old one, leaving two probe loops running for the same backend until process exit. The guard now mirrors EnableBackend's early-return on a non-target state.
This commit is contained in:
@@ -385,3 +385,45 @@ func TestPauseResume(t *testing.T) {
|
||||
t.Error("ResumeBackend on disabled backend: expected error")
|
||||
}
|
||||
}
|
||||
|
||||
// TestResumeNonPausedIsNoOp guards against a regression where ResumeBackend
|
||||
// on a running (non-paused) backend would overwrite w.cancel and spawn an
|
||||
// extra probe goroutine, orphaning the original one. The worker's wakeCh
|
||||
// must stay identical — a new one would indicate the goroutine-start branch
|
||||
// ran.
|
||||
func TestResumeNonPausedIsNoOp(t *testing.T) {
|
||||
cfg := makeTestConfig(time.Hour, 3, 2)
|
||||
c := New(cfg)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go c.fanOut(ctx)
|
||||
|
||||
origWakeCh := make(chan struct{}, 1)
|
||||
c.mu.Lock()
|
||||
c.runCtx = ctx
|
||||
_, wCancel := context.WithCancel(ctx)
|
||||
c.workers["be0"] = &worker{
|
||||
backend: health.New("be0", net.ParseIP("10.0.0.2"), 2, 3),
|
||||
hc: cfg.HealthChecks["icmp"],
|
||||
entry: cfg.Backends["be0"],
|
||||
cancel: wCancel,
|
||||
wakeCh: origWakeCh,
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
b, err := c.ResumeBackend("be0")
|
||||
if err != nil {
|
||||
t.Fatalf("ResumeBackend: %v", err)
|
||||
}
|
||||
if b.Health.State != health.StateUnknown {
|
||||
t.Errorf("state=%s, want unknown (resume on non-paused should not transition)", b.Health.State)
|
||||
}
|
||||
|
||||
c.mu.RLock()
|
||||
gotWakeCh := c.workers["be0"].wakeCh
|
||||
c.mu.RUnlock()
|
||||
if gotWakeCh != origWakeCh {
|
||||
t.Error("wakeCh was replaced — ResumeBackend spawned a spurious goroutine")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user