mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-14 20:16:36 +00:00
refactor: track routine running instead
This commit is contained in:
parent
9ca8b44870
commit
6d048460ce
2 changed files with 13 additions and 6 deletions
|
|
@ -19,6 +19,7 @@ package snapshot
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/fastcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
|
|
@ -43,6 +44,7 @@ type diskLayer struct {
|
||||||
genMarker []byte // Marker for the state that's indexed during initial layer generation
|
genMarker []byte // Marker for the state that's indexed during initial layer generation
|
||||||
genPending chan struct{} // Notification channel when generation is done (test synchronicity)
|
genPending chan struct{} // Notification channel when generation is done (test synchronicity)
|
||||||
genAbort chan chan *generatorStats // Notification channel to abort generating the snapshot in this layer
|
genAbort chan chan *generatorStats // Notification channel to abort generating the snapshot in this layer
|
||||||
|
genRunning atomic.Bool // Tracks whether the generator goroutine is actually running
|
||||||
|
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
@ -192,10 +194,14 @@ func (dl *diskLayer) Update(blockHash common.Hash, accounts map[common.Hash][]by
|
||||||
|
|
||||||
// stopGeneration aborts the state snapshot generation if it is currently running.
|
// stopGeneration aborts the state snapshot generation if it is currently running.
|
||||||
func (dl *diskLayer) stopGeneration() {
|
func (dl *diskLayer) stopGeneration() {
|
||||||
// Check if generation goroutine is running by checking if genAbort channel exists.
|
// Check if generation goroutine is actually running
|
||||||
// Note: genMarker can be nil even when the generator is still running (waiting
|
|
||||||
// for abort signal after completing generation), so we check genAbort instead.
|
|
||||||
//
|
//
|
||||||
|
// Note: genMarker can be nil even when the generator is still running (waiting
|
||||||
|
// for abort signal after completing generation), so we can't rely on genMarker.
|
||||||
|
if !dl.genRunning.Load() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Use write lock to ensure only one goroutine can stop generation at a time,
|
// Use write lock to ensure only one goroutine can stop generation at a time,
|
||||||
// preventing a race where multiple callers might try to send abort signals.
|
// preventing a race where multiple callers might try to send abort signals.
|
||||||
dl.lock.Lock()
|
dl.lock.Lock()
|
||||||
|
|
@ -210,14 +216,12 @@ func (dl *diskLayer) stopGeneration() {
|
||||||
dl.lock.Unlock()
|
dl.lock.Unlock()
|
||||||
|
|
||||||
// Perform the channel handshake without holding the lock to avoid deadlocks.
|
// Perform the channel handshake without holding the lock to avoid deadlocks.
|
||||||
// Use a timeout to handle cases where the generator goroutine may have exited
|
|
||||||
// unexpectedly (e.g., due to panic or other runtime errors).
|
|
||||||
abort := make(chan *generatorStats)
|
abort := make(chan *generatorStats)
|
||||||
select {
|
select {
|
||||||
case genAbort <- abort:
|
case genAbort <- abort:
|
||||||
// Generator received the abort signal, wait for it to respond
|
// Generator received the abort signal, wait for it to respond
|
||||||
<-abort
|
<-abort
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
log.Warn("Snapshot generator did not respond to stop signal, it may have crashed")
|
log.Error("Snapshot generator did not respond despite being marked as running")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -648,6 +648,9 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
||||||
// gathering and logging, since the method surfs the blocks as they arrive, often
|
// gathering and logging, since the method surfs the blocks as they arrive, often
|
||||||
// being restarted.
|
// being restarted.
|
||||||
func (dl *diskLayer) generate(stats *generatorStats) {
|
func (dl *diskLayer) generate(stats *generatorStats) {
|
||||||
|
dl.genRunning.Store(true)
|
||||||
|
defer dl.genRunning.Store(false)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
accMarker []byte
|
accMarker []byte
|
||||||
abort chan *generatorStats
|
abort chan *generatorStats
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue