p2p/protocols: fix possible metrics loss in AccountingMetrics (#18956)
This commit is contained in:
parent
a0ac3b6a1a
commit
74c38902ec
@ -36,6 +36,13 @@ type AccountingMetrics struct {
|
|||||||
//for a graceful cleanup
|
//for a graceful cleanup
|
||||||
func (am *AccountingMetrics) Close() {
|
func (am *AccountingMetrics) Close() {
|
||||||
close(am.reporter.quit)
|
close(am.reporter.quit)
|
||||||
|
// wait for reporter loop to finish saving metrics
|
||||||
|
// before reporter database is closed
|
||||||
|
select {
|
||||||
|
case <-time.After(10 * time.Second):
|
||||||
|
log.Error("accounting metrics reporter timeout")
|
||||||
|
case <-am.reporter.done:
|
||||||
|
}
|
||||||
am.reporter.db.Close()
|
am.reporter.db.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +53,7 @@ type reporter struct {
|
|||||||
interval time.Duration //duration at which the reporter will persist metrics
|
interval time.Duration //duration at which the reporter will persist metrics
|
||||||
db *leveldb.DB //the actual DB
|
db *leveldb.DB //the actual DB
|
||||||
quit chan struct{} //quit the reporter loop
|
quit chan struct{} //quit the reporter loop
|
||||||
|
done chan struct{} //signal that reporter loop is done
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewMetricsDB creates a new LevelDB instance used to persist metrics defined
|
//NewMetricsDB creates a new LevelDB instance used to persist metrics defined
|
||||||
@ -92,6 +100,7 @@ func NewAccountingMetrics(r metrics.Registry, d time.Duration, path string) *Acc
|
|||||||
interval: d,
|
interval: d,
|
||||||
db: db,
|
db: db,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
|
done: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
//run the go routine
|
//run the go routine
|
||||||
@ -106,6 +115,9 @@ func NewAccountingMetrics(r metrics.Registry, d time.Duration, path string) *Acc
|
|||||||
|
|
||||||
//run is the goroutine which periodically sends the metrics to the configured LevelDB
|
//run is the goroutine which periodically sends the metrics to the configured LevelDB
|
||||||
func (r *reporter) run() {
|
func (r *reporter) run() {
|
||||||
|
// signal that the reporter loop is done
|
||||||
|
defer close(r.done)
|
||||||
|
|
||||||
intervalTicker := time.NewTicker(r.interval)
|
intervalTicker := time.NewTicker(r.interval)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -121,6 +133,9 @@ func (r *reporter) run() {
|
|||||||
}
|
}
|
||||||
case <-r.quit:
|
case <-r.quit:
|
||||||
//graceful shutdown
|
//graceful shutdown
|
||||||
|
if err := r.save(); err != nil {
|
||||||
|
log.Error("unable to send metrics to LevelDB", "err", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user