7245ac2b69
1. SyncerState contains a mutex and should never be copied. Honestly, this case was probably fine but it's just as easy to create a separate snapshot type and easier to reason about. 2. We need to initialize the syncStates array once at start, before accessing it. By each syncer state inside each worker, we were racing with calls to `State()`. Again, this was probably benign, but I don't trust optimizing compilers.
85 lines
1.4 KiB
Go
85 lines
1.4 KiB
Go
package chain
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
"github.com/filecoin-project/lotus/build"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
)
|
|
|
|
type SyncerStateSnapshot struct {
|
|
Target *types.TipSet
|
|
Base *types.TipSet
|
|
Stage api.SyncStateStage
|
|
Height abi.ChainEpoch
|
|
Message string
|
|
Start time.Time
|
|
End time.Time
|
|
}
|
|
|
|
type SyncerState struct {
|
|
lk sync.Mutex
|
|
data SyncerStateSnapshot
|
|
}
|
|
|
|
func (ss *SyncerState) SetStage(v api.SyncStateStage) {
|
|
if ss == nil {
|
|
return
|
|
}
|
|
|
|
ss.lk.Lock()
|
|
defer ss.lk.Unlock()
|
|
ss.data.Stage = v
|
|
if v == api.StageSyncComplete {
|
|
ss.data.End = build.Clock.Now()
|
|
}
|
|
}
|
|
|
|
func (ss *SyncerState) Init(base, target *types.TipSet) {
|
|
if ss == nil {
|
|
return
|
|
}
|
|
|
|
ss.lk.Lock()
|
|
defer ss.lk.Unlock()
|
|
ss.data.Target = target
|
|
ss.data.Base = base
|
|
ss.data.Stage = api.StageHeaders
|
|
ss.data.Height = 0
|
|
ss.data.Message = ""
|
|
ss.data.Start = build.Clock.Now()
|
|
ss.data.End = time.Time{}
|
|
}
|
|
|
|
func (ss *SyncerState) SetHeight(h abi.ChainEpoch) {
|
|
if ss == nil {
|
|
return
|
|
}
|
|
|
|
ss.lk.Lock()
|
|
defer ss.lk.Unlock()
|
|
ss.data.Height = h
|
|
}
|
|
|
|
func (ss *SyncerState) Error(err error) {
|
|
if ss == nil {
|
|
return
|
|
}
|
|
|
|
ss.lk.Lock()
|
|
defer ss.lk.Unlock()
|
|
ss.data.Message = err.Error()
|
|
ss.data.Stage = api.StageSyncErrored
|
|
ss.data.End = build.Clock.Now()
|
|
}
|
|
|
|
func (ss *SyncerState) Snapshot() SyncerStateSnapshot {
|
|
ss.lk.Lock()
|
|
defer ss.lk.Unlock()
|
|
return ss.data
|
|
}
|