diff options
author | Elad <theman@elad.im> | 2019-02-13 15:15:03 +0800 |
---|---|---|
committer | Rafael Matias <rafael@skyle.net> | 2019-02-19 20:11:51 +0800 |
commit | a0127019c3d516e8d8cf83839583bcf71af763e0 (patch) | |
tree | b034a4dab0cce6efcb2a9038c7a030b29065ce9b | |
parent | 7a333e41046e818604f07fcfd6654af30fe70bf9 (diff) | |
download | go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.tar go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.tar.gz go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.tar.bz2 go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.tar.lz go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.tar.xz go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.tar.zst go-tangerine-a0127019c3d516e8d8cf83839583bcf71af763e0.zip |
swarm: fix uptime gauge update goroutine leak by introducing cleanup functions (#19040)
(cherry picked from commit d596bea2d501d20b92e0fd4baa8bba682157dfa7)
-rw-r--r-- | swarm/swarm.go | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/swarm/swarm.go b/swarm/swarm.go index cba4e73ef..cb914d39a 100644 --- a/swarm/swarm.go +++ b/swarm/swarm.go @@ -79,7 +79,7 @@ type Swarm struct { swap *swap.Swap stateStore *state.DBStore accountingMetrics *protocols.AccountingMetrics - startTime time.Time + cleanupFuncs []func() error tracerClose io.Closer } @@ -106,9 +106,10 @@ func NewSwarm(config *api.Config, mockStore *mock.NodeStore) (self *Swarm, err e } self = &Swarm{ - config: config, - backend: backend, - privateKey: config.ShiftPrivateKey(), + config: config, + backend: backend, + privateKey: config.ShiftPrivateKey(), + cleanupFuncs: []func() error{}, } log.Debug("Setting up Swarm service components") @@ -344,7 +345,7 @@ Start is called when the stack is started */ // implements the node.Service interface func (self *Swarm) Start(srv *p2p.Server) error { - self.startTime = time.Now() + startTime := time.Now() self.tracerClose = tracing.Closer @@ -396,26 +397,28 @@ func (self *Swarm) Start(srv *p2p.Server) error { }() } - self.periodicallyUpdateGauges() + doneC := make(chan struct{}) - startCounter.Inc(1) - self.streamer.Start(srv) - return nil -} + self.cleanupFuncs = append(self.cleanupFuncs, func() error { + close(doneC) + return nil + }) -func (self *Swarm) periodicallyUpdateGauges() { - ticker := time.NewTicker(updateGaugesPeriod) - - go func() { - for range ticker.C { - self.updateGauges() + go func(time.Time) { + for { + select { + case <-time.After(updateGaugesPeriod): + uptimeGauge.Update(time.Since(startTime).Nanoseconds()) + requestsCacheGauge.Update(int64(self.netStore.RequestsCacheLen())) + case <-doneC: + return + } } - }() -} + }(startTime) -func (self *Swarm) updateGauges() { - uptimeGauge.Update(time.Since(self.startTime).Nanoseconds()) - requestsCacheGauge.Update(int64(self.netStore.RequestsCacheLen())) + startCounter.Inc(1) + self.streamer.Start(srv) + return nil } // implements the node.Service interface @@ -452,6 +455,14 @@ func (self *Swarm) Stop() error { if self.stateStore != nil { self.stateStore.Close() } + + for _, cleanF := range self.cleanupFuncs { + err = cleanF() + if err != nil { + log.Error("encountered an error while running cleanup function", "err", err) + break + } + } return err } |