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:
parent
ed202bf050
commit
7fe7a62991
@ -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:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user