Skip to content

Commit f991995

Browse files
rjl493456442karalabe
authored andcommitted
ethdb: gracefullly handle quit channel (#16794)
* ethdb: gratefullly handle quit channel * ethdb: minor polish
1 parent aab7ab0 commit f991995

File tree

1 file changed

+40
-34
lines changed

1 file changed

+40
-34
lines changed

ethdb/database.go

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ func (db *LDBDatabase) Close() {
141141
if err := <-errc; err != nil {
142142
db.log.Error("Metrics collection failed", "err", err)
143143
}
144+
db.quitChan = nil
144145
}
145146
err := db.db.Close()
146147
if err == nil {
@@ -189,7 +190,7 @@ func (db *LDBDatabase) Meter(prefix string) {
189190
// 3 | 570 | 1113.18458 | 0.00000 | 0.00000 | 0.00000
190191
//
191192
// This is how the write delay look like (currently):
192-
// DelayN:5 Delay:406.604657ms
193+
// DelayN:5 Delay:406.604657ms Paused: false
193194
//
194195
// This is how the iostats look like (currently):
195196
// Read(MB):3895.04860 Write(MB):3654.64712
@@ -210,13 +211,19 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
210211
lastWritePaused time.Time
211212
)
212213

214+
var (
215+
errc chan error
216+
merr error
217+
)
218+
213219
// Iterate ad infinitum and collect the stats
214-
for i := 1; ; i++ {
220+
for i := 1; errc == nil && merr == nil; i++ {
215221
// Retrieve the database stats
216222
stats, err := db.db.GetProperty("leveldb.stats")
217223
if err != nil {
218224
db.log.Error("Failed to read database stats", "err", err)
219-
return
225+
merr = err
226+
continue
220227
}
221228
// Find the compaction table, skip the header
222229
lines := strings.Split(stats, "\n")
@@ -225,7 +232,8 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
225232
}
226233
if len(lines) <= 3 {
227234
db.log.Error("Compaction table not found")
228-
return
235+
merr = errors.New("compaction table not found")
236+
continue
229237
}
230238
lines = lines[3:]
231239

@@ -242,7 +250,8 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
242250
value, err := strconv.ParseFloat(strings.TrimSpace(counter), 64)
243251
if err != nil {
244252
db.log.Error("Compaction entry parsing failed", "err", err)
245-
return
253+
merr = err
254+
continue
246255
}
247256
compactions[i%2][idx] += value
248257
}
@@ -262,7 +271,8 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
262271
writedelay, err := db.db.GetProperty("leveldb.writedelay")
263272
if err != nil {
264273
db.log.Error("Failed to read database write delay statistic", "err", err)
265-
return
274+
merr = err
275+
continue
266276
}
267277
var (
268278
delayN int64
@@ -272,12 +282,14 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
272282
)
273283
if n, err := fmt.Sscanf(writedelay, "DelayN:%d Delay:%s Paused:%t", &delayN, &delayDuration, &paused); n != 3 || err != nil {
274284
db.log.Error("Write delay statistic not found")
275-
return
285+
merr = err
286+
continue
276287
}
277288
duration, err = time.ParseDuration(delayDuration)
278289
if err != nil {
279290
db.log.Error("Failed to parse delay duration", "err", err)
280-
return
291+
merr = err
292+
continue
281293
}
282294
if db.writeDelayNMeter != nil {
283295
db.writeDelayNMeter.Mark(delayN - delaystats[0])
@@ -317,53 +329,47 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
317329
ioStats, err := db.db.GetProperty("leveldb.iostats")
318330
if err != nil {
319331
db.log.Error("Failed to read database iostats", "err", err)
320-
return
332+
merr = err
333+
continue
321334
}
335+
var nRead, nWrite float64
322336
parts := strings.Split(ioStats, " ")
323337
if len(parts) < 2 {
324338
db.log.Error("Bad syntax of ioStats", "ioStats", ioStats)
325-
return
339+
merr = fmt.Errorf("bad syntax of ioStats %s", ioStats)
340+
continue
326341
}
327-
r := strings.Split(parts[0], ":")
328-
if len(r) < 2 {
342+
if n, err := fmt.Sscanf(parts[0], "Read(MB):%f", &nRead); n != 1 || err != nil {
329343
db.log.Error("Bad syntax of read entry", "entry", parts[0])
330-
return
331-
}
332-
read, err := strconv.ParseFloat(r[1], 64)
333-
if err != nil {
334-
db.log.Error("Read entry parsing failed", "err", err)
335-
return
344+
merr = err
345+
continue
336346
}
337-
w := strings.Split(parts[1], ":")
338-
if len(w) < 2 {
347+
if n, err := fmt.Sscanf(parts[1], "Write(MB):%f", &nWrite); n != 1 || err != nil {
339348
db.log.Error("Bad syntax of write entry", "entry", parts[1])
340-
return
341-
}
342-
write, err := strconv.ParseFloat(w[1], 64)
343-
if err != nil {
344-
db.log.Error("Write entry parsing failed", "err", err)
345-
return
349+
merr = err
350+
continue
346351
}
347352
if db.diskReadMeter != nil {
348-
db.diskReadMeter.Mark(int64((read - iostats[0]) * 1024 * 1024))
353+
db.diskReadMeter.Mark(int64((nRead - iostats[0]) * 1024 * 1024))
349354
}
350355
if db.diskWriteMeter != nil {
351-
db.diskWriteMeter.Mark(int64((write - iostats[1]) * 1024 * 1024))
356+
db.diskWriteMeter.Mark(int64((nWrite - iostats[1]) * 1024 * 1024))
352357
}
353-
iostats[0] = read
354-
iostats[1] = write
358+
iostats[0], iostats[1] = nRead, nWrite
355359

356360
// Sleep a bit, then repeat the stats collection
357361
select {
358-
case errc := <-db.quitChan:
362+
case errc = <-db.quitChan:
359363
// Quit requesting, stop hammering the database
360-
errc <- nil
361-
return
362-
363364
case <-time.After(refresh):
364365
// Timeout, gather a new set of stats
365366
}
366367
}
368+
369+
if errc == nil {
370+
errc = <-db.quitChan
371+
}
372+
errc <- merr
367373
}
368374

369375
func (db *LDBDatabase) NewBatch() Batch {

0 commit comments

Comments
 (0)