Skip to content

Commit b671640

Browse files
acuddshulyak
authored andcommitted
swarm: fix uptime gauge update goroutine leak by introducing cleanup functions (ethereum#19040)
(cherry picked from commit d596bea)
1 parent 5cab8cd commit b671640

File tree

1 file changed

+32
-21
lines changed

1 file changed

+32
-21
lines changed

swarm/swarm.go

+32-21
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ type Swarm struct {
7979
swap *swap.Swap
8080
stateStore *state.DBStore
8181
accountingMetrics *protocols.AccountingMetrics
82-
startTime time.Time
82+
cleanupFuncs []func() error
8383

8484
tracerClose io.Closer
8585
}
@@ -106,9 +106,10 @@ func NewSwarm(config *api.Config, mockStore *mock.NodeStore) (self *Swarm, err e
106106
}
107107

108108
self = &Swarm{
109-
config: config,
110-
backend: backend,
111-
privateKey: config.ShiftPrivateKey(),
109+
config: config,
110+
backend: backend,
111+
privateKey: config.ShiftPrivateKey(),
112+
cleanupFuncs: []func() error{},
112113
}
113114
log.Debug("Setting up Swarm service components")
114115

@@ -344,7 +345,7 @@ Start is called when the stack is started
344345
*/
345346
// implements the node.Service interface
346347
func (self *Swarm) Start(srv *p2p.Server) error {
347-
self.startTime = time.Now()
348+
startTime := time.Now()
348349

349350
self.tracerClose = tracing.Closer
350351

@@ -396,26 +397,28 @@ func (self *Swarm) Start(srv *p2p.Server) error {
396397
}()
397398
}
398399

399-
self.periodicallyUpdateGauges()
400+
doneC := make(chan struct{})
400401

401-
startCounter.Inc(1)
402-
self.streamer.Start(srv)
403-
return nil
404-
}
402+
self.cleanupFuncs = append(self.cleanupFuncs, func() error {
403+
close(doneC)
404+
return nil
405+
})
405406

406-
func (self *Swarm) periodicallyUpdateGauges() {
407-
ticker := time.NewTicker(updateGaugesPeriod)
408-
409-
go func() {
410-
for range ticker.C {
411-
self.updateGauges()
407+
go func(time.Time) {
408+
for {
409+
select {
410+
case <-time.After(updateGaugesPeriod):
411+
uptimeGauge.Update(time.Since(startTime).Nanoseconds())
412+
requestsCacheGauge.Update(int64(self.netStore.RequestsCacheLen()))
413+
case <-doneC:
414+
return
415+
}
412416
}
413-
}()
414-
}
417+
}(startTime)
415418

416-
func (self *Swarm) updateGauges() {
417-
uptimeGauge.Update(time.Since(self.startTime).Nanoseconds())
418-
requestsCacheGauge.Update(int64(self.netStore.RequestsCacheLen()))
419+
startCounter.Inc(1)
420+
self.streamer.Start(srv)
421+
return nil
419422
}
420423

421424
// implements the node.Service interface
@@ -452,6 +455,14 @@ func (self *Swarm) Stop() error {
452455
if self.stateStore != nil {
453456
self.stateStore.Close()
454457
}
458+
459+
for _, cleanF := range self.cleanupFuncs {
460+
err = cleanF()
461+
if err != nil {
462+
log.Error("encountered an error while running cleanup function", "err", err)
463+
break
464+
}
465+
}
455466
return err
456467
}
457468

0 commit comments

Comments
 (0)