app/vminsert/netstorage: refactor snb rebuild

Signed-off-by: Zakhar Bessarab <z.bessarab@victoriametrics.com>
This commit is contained in:
Zakhar Bessarab 2024-07-29 17:23:22 +04:00
parent 2b39ee785c
commit 1272a7f743
No known key found for this signature in database
GPG key ID: 932B34D6FE062023

View file

@ -648,41 +648,23 @@ func initStorageNodes(addrs []string, hashSeed uint64) *storageNodesBucket {
// Watch for node become healthy and rebuild snb. // Watch for node become healthy and rebuild snb.
for _, sn := range brokenNodes { for _, sn := range brokenNodes {
wg.Add(1) wg.Add(1)
go func(sn *storageNode) { sn := sn
go watchStorageNodeHealthy(sn, func() {
defer wg.Done() defer wg.Done()
// rebuild snb in order to update consistent hash with an ID of the healthy storage node
for { for {
sn.brLock.Lock() currentSnb := getStorageNodesBucket()
for !sn.isReady() { newSnb := initStorageNodes(addrs, hashSeed)
select { if !storageNodes.CompareAndSwap(currentSnb, newSnb) {
case <-sn.stopCh: // snb has been changed, so we need to stop the newSnb and try again
sn.brLock.Unlock() mustStopStorageNodes(newSnb)
return continue
default:
sn.brCond.Wait()
}
}
sn.brLock.Unlock()
select {
case <-sn.stopCh:
return
default:
}
if sn.isReady() {
again:
currentSnb := getStorageNodesBucket()
newSnb := initStorageNodes(addrs, hashSeed)
if !storageNodes.CompareAndSwap(currentSnb, newSnb) {
mustStopStorageNodes(newSnb)
goto again
}
mustStopStorageNodes(currentSnb)
break
} }
// stop previous snb and exit
mustStopStorageNodes(currentSnb)
break
} }
}(sn) })
} }
return snb return snb
@ -697,6 +679,34 @@ func mustStopStorageNodes(snb *storageNodesBucket) {
metrics.UnregisterSet(snb.ms, true) metrics.UnregisterSet(snb.ms, true)
} }
// watchStorageNodeHealthy watches for sn become healthy and calls cb once it is ready.
func watchStorageNodeHealthy(sn *storageNode, cb func()) {
for {
sn.brLock.Lock()
for !sn.isReady() {
select {
case <-sn.stopCh:
sn.brLock.Unlock()
return
default:
sn.brCond.Wait()
}
}
sn.brLock.Unlock()
select {
case <-sn.stopCh:
return
default:
}
if sn.isReady() {
cb()
return
}
}
}
// rerouteRowsToReadyStorageNodes reroutes src from not ready snSource to ready storage nodes. // rerouteRowsToReadyStorageNodes reroutes src from not ready snSource to ready storage nodes.
// //
// The function blocks until src is fully re-routed. // The function blocks until src is fully re-routed.