fix(cluster): wake the long-lived lock renewal loop promptly on Stop

StartLongLivedLock's renewal loop slept uninterruptibly between attempts,
up to 5*renewInterval (2.5*lockTTL) while unlocked. Stop() waits only
lockTTL+2s for the goroutine to exit, so a Stop() during that backoff
would time out before the goroutine woke and closed renewalDone,
breaking the shutdown synchronization. Sleep on a timer with a select on
cancelCh so the loop exits immediately.
This commit is contained in:
Chris Lu 2026-05-20 14:51:48 -07:00
parent ed202bf050
commit 7fe7a62991

View File

@ -153,15 +153,21 @@ func (lc *LockClient) StartLongLivedLock(key string, owner string, onLockOwnerCh
onLockOwnerChange(lock.LockOwner())
lockOwner = lock.LockOwner()
}
// Sleep until the next attempt, but wake immediately on Stop() so
// the goroutine exits and closes renewalDone before Stop()'s bounded
// wait elapses. An uninterruptible sleep here (up to 5*renewInterval
// when unlocked) can outlast that wait and break the shutdown
// synchronization.
sleepFor := renewInterval
if !isLocked {
sleepFor = 5 * renewInterval
}
timer := time.NewTimer(sleepFor)
select {
case <-lock.cancelCh:
timer.Stop()
return
default:
if isLocked {
time.Sleep(renewInterval)
} else {
time.Sleep(5 * renewInterval)
}
case <-timer.C:
}
}
}()