@@ -141,6 +141,7 @@ func (db *LDBDatabase) Close() {
141
141
if err := <- errc ; err != nil {
142
142
db .log .Error ("Metrics collection failed" , "err" , err )
143
143
}
144
+ db .quitChan = nil
144
145
}
145
146
err := db .db .Close ()
146
147
if err == nil {
@@ -189,7 +190,7 @@ func (db *LDBDatabase) Meter(prefix string) {
189
190
// 3 | 570 | 1113.18458 | 0.00000 | 0.00000 | 0.00000
190
191
//
191
192
// This is how the write delay look like (currently):
192
- // DelayN:5 Delay:406.604657ms
193
+ // DelayN:5 Delay:406.604657ms Paused: false
193
194
//
194
195
// This is how the iostats look like (currently):
195
196
// Read(MB):3895.04860 Write(MB):3654.64712
@@ -210,13 +211,19 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
210
211
lastWritePaused time.Time
211
212
)
212
213
214
+ var (
215
+ errc chan error
216
+ merr error
217
+ )
218
+
213
219
// Iterate ad infinitum and collect the stats
214
- for i := 1 ; ; i ++ {
220
+ for i := 1 ; errc == nil && merr == nil ; i ++ {
215
221
// Retrieve the database stats
216
222
stats , err := db .db .GetProperty ("leveldb.stats" )
217
223
if err != nil {
218
224
db .log .Error ("Failed to read database stats" , "err" , err )
219
- return
225
+ merr = err
226
+ continue
220
227
}
221
228
// Find the compaction table, skip the header
222
229
lines := strings .Split (stats , "\n " )
@@ -225,7 +232,8 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
225
232
}
226
233
if len (lines ) <= 3 {
227
234
db .log .Error ("Compaction table not found" )
228
- return
235
+ merr = errors .New ("compaction table not found" )
236
+ continue
229
237
}
230
238
lines = lines [3 :]
231
239
@@ -242,7 +250,8 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
242
250
value , err := strconv .ParseFloat (strings .TrimSpace (counter ), 64 )
243
251
if err != nil {
244
252
db .log .Error ("Compaction entry parsing failed" , "err" , err )
245
- return
253
+ merr = err
254
+ continue
246
255
}
247
256
compactions [i % 2 ][idx ] += value
248
257
}
@@ -262,7 +271,8 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
262
271
writedelay , err := db .db .GetProperty ("leveldb.writedelay" )
263
272
if err != nil {
264
273
db .log .Error ("Failed to read database write delay statistic" , "err" , err )
265
- return
274
+ merr = err
275
+ continue
266
276
}
267
277
var (
268
278
delayN int64
@@ -272,12 +282,14 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
272
282
)
273
283
if n , err := fmt .Sscanf (writedelay , "DelayN:%d Delay:%s Paused:%t" , & delayN , & delayDuration , & paused ); n != 3 || err != nil {
274
284
db .log .Error ("Write delay statistic not found" )
275
- return
285
+ merr = err
286
+ continue
276
287
}
277
288
duration , err = time .ParseDuration (delayDuration )
278
289
if err != nil {
279
290
db .log .Error ("Failed to parse delay duration" , "err" , err )
280
- return
291
+ merr = err
292
+ continue
281
293
}
282
294
if db .writeDelayNMeter != nil {
283
295
db .writeDelayNMeter .Mark (delayN - delaystats [0 ])
@@ -317,53 +329,47 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
317
329
ioStats , err := db .db .GetProperty ("leveldb.iostats" )
318
330
if err != nil {
319
331
db .log .Error ("Failed to read database iostats" , "err" , err )
320
- return
332
+ merr = err
333
+ continue
321
334
}
335
+ var nRead , nWrite float64
322
336
parts := strings .Split (ioStats , " " )
323
337
if len (parts ) < 2 {
324
338
db .log .Error ("Bad syntax of ioStats" , "ioStats" , ioStats )
325
- return
339
+ merr = fmt .Errorf ("bad syntax of ioStats %s" , ioStats )
340
+ continue
326
341
}
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 {
329
343
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
336
346
}
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 {
339
348
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
346
351
}
347
352
if db .diskReadMeter != nil {
348
- db .diskReadMeter .Mark (int64 ((read - iostats [0 ]) * 1024 * 1024 ))
353
+ db .diskReadMeter .Mark (int64 ((nRead - iostats [0 ]) * 1024 * 1024 ))
349
354
}
350
355
if db .diskWriteMeter != nil {
351
- db .diskWriteMeter .Mark (int64 ((write - iostats [1 ]) * 1024 * 1024 ))
356
+ db .diskWriteMeter .Mark (int64 ((nWrite - iostats [1 ]) * 1024 * 1024 ))
352
357
}
353
- iostats [0 ] = read
354
- iostats [1 ] = write
358
+ iostats [0 ], iostats [1 ] = nRead , nWrite
355
359
356
360
// Sleep a bit, then repeat the stats collection
357
361
select {
358
- case errc : = <- db .quitChan :
362
+ case errc = <- db .quitChan :
359
363
// Quit requesting, stop hammering the database
360
- errc <- nil
361
- return
362
-
363
364
case <- time .After (refresh ):
364
365
// Timeout, gather a new set of stats
365
366
}
366
367
}
368
+
369
+ if errc == nil {
370
+ errc = <- db .quitChan
371
+ }
372
+ errc <- merr
367
373
}
368
374
369
375
func (db * LDBDatabase ) NewBatch () Batch {
0 commit comments