ethdb/leveldb : use close(quit) to quit meter routine

This commit is contained in:
ucwong 2020-04-25 07:05:06 +00:00
parent 8d163ae08b
commit b960717392

View file

@ -145,14 +145,8 @@ func (db *Database) Close() error {
db.quitLock.Lock() db.quitLock.Lock()
defer db.quitLock.Unlock() defer db.quitLock.Unlock()
if db.quitChan != nil { close(db.quitChan)
errc := make(chan error)
db.quitChan <- errc
if err := <-errc; err != nil {
db.log.Error("Metrics collection failed", "err", err)
}
db.quitChan = nil
}
db.wg.Wait() db.wg.Wait()
return db.db.Close() return db.db.Close()
} }
@ -249,19 +243,15 @@ func (db *Database) meter(refresh time.Duration) {
delaystats [2]int64 delaystats [2]int64
lastWritePaused time.Time lastWritePaused time.Time
) )
timer := time.NewTimer(refresh)
var ( defer timer.Stop()
errc chan error
merr error
)
// Iterate ad infinitum and collect the stats // Iterate ad infinitum and collect the stats
for i := 1; errc == nil && merr == nil; i++ { for i := 1; ; i++ {
// Retrieve the database stats // Retrieve the database stats
stats, err := db.db.GetProperty("leveldb.stats") stats, err := db.db.GetProperty("leveldb.stats")
if err != nil { if err != nil {
db.log.Error("Failed to read database stats", "err", err) db.log.Error("Failed to read database stats", "err", err)
merr = err
continue continue
} }
// Find the compaction table, skip the header // Find the compaction table, skip the header
@ -271,7 +261,6 @@ func (db *Database) meter(refresh time.Duration) {
} }
if len(lines) <= 3 { if len(lines) <= 3 {
db.log.Error("Compaction leveldbTable not found") db.log.Error("Compaction leveldbTable not found")
merr = errors.New("compaction leveldbTable not found")
continue continue
} }
lines = lines[3:] lines = lines[3:]
@ -289,7 +278,6 @@ func (db *Database) meter(refresh time.Duration) {
value, err := strconv.ParseFloat(strings.TrimSpace(counter), 64) value, err := strconv.ParseFloat(strings.TrimSpace(counter), 64)
if err != nil { if err != nil {
db.log.Error("Compaction entry parsing failed", "err", err) db.log.Error("Compaction entry parsing failed", "err", err)
merr = err
continue continue
} }
compactions[i%2][idx] += value compactions[i%2][idx] += value
@ -312,7 +300,6 @@ func (db *Database) meter(refresh time.Duration) {
writedelay, err := db.db.GetProperty("leveldb.writedelay") writedelay, err := db.db.GetProperty("leveldb.writedelay")
if err != nil { if err != nil {
db.log.Error("Failed to read database write delay statistic", "err", err) db.log.Error("Failed to read database write delay statistic", "err", err)
merr = err
continue continue
} }
var ( var (
@ -323,13 +310,11 @@ func (db *Database) meter(refresh time.Duration) {
) )
if n, err := fmt.Sscanf(writedelay, "DelayN:%d Delay:%s Paused:%t", &delayN, &delayDuration, &paused); n != 3 || err != nil { if n, err := fmt.Sscanf(writedelay, "DelayN:%d Delay:%s Paused:%t", &delayN, &delayDuration, &paused); n != 3 || err != nil {
db.log.Error("Write delay statistic not found") db.log.Error("Write delay statistic not found")
merr = err
continue continue
} }
duration, err = time.ParseDuration(delayDuration) duration, err = time.ParseDuration(delayDuration)
if err != nil { if err != nil {
db.log.Error("Failed to parse delay duration", "err", err) db.log.Error("Failed to parse delay duration", "err", err)
merr = err
continue continue
} }
if db.writeDelayNMeter != nil { if db.writeDelayNMeter != nil {
@ -351,24 +336,20 @@ func (db *Database) meter(refresh time.Duration) {
ioStats, err := db.db.GetProperty("leveldb.iostats") ioStats, err := db.db.GetProperty("leveldb.iostats")
if err != nil { if err != nil {
db.log.Error("Failed to read database iostats", "err", err) db.log.Error("Failed to read database iostats", "err", err)
merr = err
continue continue
} }
var nRead, nWrite float64 var nRead, nWrite float64
parts := strings.Split(ioStats, " ") parts := strings.Split(ioStats, " ")
if len(parts) < 2 { if len(parts) < 2 {
db.log.Error("Bad syntax of ioStats", "ioStats", ioStats) db.log.Error("Bad syntax of ioStats", "ioStats", ioStats)
merr = fmt.Errorf("bad syntax of ioStats %s", ioStats)
continue continue
} }
if n, err := fmt.Sscanf(parts[0], "Read(MB):%f", &nRead); n != 1 || err != nil { if n, err := fmt.Sscanf(parts[0], "Read(MB):%f", &nRead); n != 1 || err != nil {
db.log.Error("Bad syntax of read entry", "entry", parts[0]) db.log.Error("Bad syntax of read entry", "entry", parts[0])
merr = err
continue continue
} }
if n, err := fmt.Sscanf(parts[1], "Write(MB):%f", &nWrite); n != 1 || err != nil { if n, err := fmt.Sscanf(parts[1], "Write(MB):%f", &nWrite); n != 1 || err != nil {
db.log.Error("Bad syntax of write entry", "entry", parts[1]) db.log.Error("Bad syntax of write entry", "entry", parts[1])
merr = err
continue continue
} }
if db.diskReadMeter != nil { if db.diskReadMeter != nil {
@ -382,7 +363,6 @@ func (db *Database) meter(refresh time.Duration) {
compCount, err := db.db.GetProperty("leveldb.compcount") compCount, err := db.db.GetProperty("leveldb.compcount")
if err != nil { if err != nil {
db.log.Error("Failed to read database iostats", "err", err) db.log.Error("Failed to read database iostats", "err", err)
merr = err
continue continue
} }
@ -394,7 +374,6 @@ func (db *Database) meter(refresh time.Duration) {
) )
if n, err := fmt.Sscanf(compCount, "MemComp:%d Level0Comp:%d NonLevel0Comp:%d SeekComp:%d", &memComp, &level0Comp, &nonLevel0Comp, &seekComp); n != 4 || err != nil { if n, err := fmt.Sscanf(compCount, "MemComp:%d Level0Comp:%d NonLevel0Comp:%d SeekComp:%d", &memComp, &level0Comp, &nonLevel0Comp, &seekComp); n != 4 || err != nil {
db.log.Error("Compaction count statistic not found") db.log.Error("Compaction count statistic not found")
merr = err
continue continue
} }
db.memCompGauge.Update(int64(memComp)) db.memCompGauge.Update(int64(memComp))
@ -404,17 +383,14 @@ func (db *Database) meter(refresh time.Duration) {
// Sleep a bit, then repeat the stats collection // Sleep a bit, then repeat the stats collection
select { select {
case errc = <-db.quitChan: case <-db.quitChan:
return
// Quit requesting, stop hammering the database // Quit requesting, stop hammering the database
case <-time.After(refresh): case <-timer.C:
timer.Reset(refresh)
// Timeout, gather a new set of stats // Timeout, gather a new set of stats
} }
} }
if errc == nil {
errc = <-db.quitChan
}
errc <- merr
} }
// batch is a write-only leveldb batch that commits changes to its host database // batch is a write-only leveldb batch that commits changes to its host database