mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
Fix RepeatTimer memory leak (#137)
fix RepeatTimer memory leak (Refs #137) * test case * drain channels on reset Leaking memory: ``` leaktest.go:144: leaktest: leaked goroutine: goroutine 116 [chan send]: github.com/tendermint/tmlibs/common.(*RepeatTimer).fireRoutine(0xc42006a410, 0xc4203403c0, 0xc42031b2c0) /go/src/github.com/tendermint/tmlibs/common/repeat_timer.go:160 +0x6e created by github.com/tendermint/tmlibs/common.(*RepeatTimer).reset /go/src/github.com/tendermint/tmlibs/common/repeat_timer.go:196 +0xe9 ``` The alternative solution could be draining channels on the client side. * add one more select instead of draining thanks to Jae
This commit is contained in:
parent
82ab92da9a
commit
52ce4c20f8
@ -155,7 +155,11 @@ func (t *RepeatTimer) fireRoutine(ch <-chan time.Time, quit <-chan struct{}) {
|
||||
for {
|
||||
select {
|
||||
case t_ := <-ch:
|
||||
t.ch <- t_
|
||||
select {
|
||||
case t.ch <- t_:
|
||||
case <-quit:
|
||||
return
|
||||
}
|
||||
case <-quit: // NOTE: `t.quit` races.
|
||||
return
|
||||
}
|
||||
@ -210,7 +214,6 @@ func (t *RepeatTimer) stop() {
|
||||
t.ticker.Stop()
|
||||
t.ticker = nil
|
||||
/*
|
||||
XXX
|
||||
From https://golang.org/pkg/time/#Ticker:
|
||||
"Stop the ticker to release associated resources"
|
||||
"After Stop, no more ticks will be sent"
|
||||
|
@ -1,10 +1,12 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fortytw2/leaktest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -102,3 +104,34 @@ func TestRepeatTimer(t *testing.T) {
|
||||
// Another stop panics.
|
||||
assert.Panics(t, func() { rt.Stop() })
|
||||
}
|
||||
|
||||
func TestRepeatTimerReset(t *testing.T) {
|
||||
// check that we are not leaking any go-routines
|
||||
defer leaktest.Check(t)()
|
||||
|
||||
timer := NewRepeatTimer("test", 20*time.Millisecond)
|
||||
defer timer.Stop()
|
||||
|
||||
// test we don't receive tick before duration ms.
|
||||
select {
|
||||
case <-timer.Chan():
|
||||
t.Fatal("did not expect to receive tick")
|
||||
default:
|
||||
}
|
||||
|
||||
timer.Reset()
|
||||
|
||||
// test we receive tick after Reset is called
|
||||
select {
|
||||
case <-timer.Chan():
|
||||
// all good
|
||||
case <-time.After(40 * time.Millisecond):
|
||||
t.Fatal("expected to receive tick after reset")
|
||||
}
|
||||
|
||||
// just random calls
|
||||
for i := 0; i < 100; i++ {
|
||||
time.Sleep(time.Duration(rand.Intn(40)) * time.Millisecond)
|
||||
timer.Reset()
|
||||
}
|
||||
}
|
||||
|
2
glide.lock
generated
2
glide.lock
generated
@ -95,6 +95,8 @@ testImports:
|
||||
version: 346938d642f2ec3594ed81d874461961cd0faa76
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/fortytw2/leaktest
|
||||
version: 3b724c3d7b8729a35bf4e577f71653aec6e53513
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
|
@ -35,3 +35,4 @@ testImport:
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
- package: github.com/fortytw2/leaktest
|
||||
|
Loading…
x
Reference in New Issue
Block a user