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