stop autofile and autogroup properly

NOTE: from the ticker#Stop documentation:

```
Stop does not close the channel, to prevent a read from the channel
succeeding incorrectly.
https://golang.org/src/time/tick.go?s=1318:1341#L35
```

Refs #2072
This commit is contained in:
Anton Kaliaev 2018-08-02 16:33:34 +04:00
parent eaa137512c
commit b33f73eaf1
No known key found for this signature in database
GPG Key ID: 7B6881D965918214
3 changed files with 20 additions and 24 deletions

View File

@ -35,18 +35,20 @@ const autoFileOpenDuration = 1000 * time.Millisecond
// Automatically closes and re-opens file for writing.
// This is useful for using a log file with the logrotate tool.
type AutoFile struct {
ID string
Path string
ticker *time.Ticker
mtx sync.Mutex
file *os.File
ID string
Path string
ticker *time.Ticker
tickerStopped chan struct{} // closed when ticker is stopped
mtx sync.Mutex
file *os.File
}
func OpenAutoFile(path string) (af *AutoFile, err error) {
af = &AutoFile{
ID: cmn.RandStr(12) + ":" + path,
Path: path,
ticker: time.NewTicker(autoFileOpenDuration),
ID: cmn.RandStr(12) + ":" + path,
Path: path,
ticker: time.NewTicker(autoFileOpenDuration),
tickerStopped: make(chan struct{}),
}
if err = af.openFile(); err != nil {
return
@ -58,18 +60,18 @@ func OpenAutoFile(path string) (af *AutoFile, err error) {
func (af *AutoFile) Close() error {
af.ticker.Stop()
close(af.tickerStopped)
err := af.closeFile()
sighupWatchers.removeAutoFile(af)
return err
}
func (af *AutoFile) processTicks() {
for {
_, ok := <-af.ticker.C
if !ok {
return // Done.
}
select {
case <-af.ticker.C:
af.closeFile()
case <-af.tickerStopped:
return
}
}

View File

@ -199,21 +199,15 @@ func (g *Group) Flush() error {
}
func (g *Group) processTicks() {
for {
_, ok := <-g.ticker.C
if !ok {
return // Done.
}
select {
case <-g.ticker.C:
g.checkHeadSizeLimit()
g.checkTotalSizeLimit()
case <-g.Quit():
return
}
}
// NOTE: for testing
func (g *Group) stopTicker() {
g.ticker.Stop()
}
// NOTE: this function is called manually in tests.
func (g *Group) checkHeadSizeLimit() {
limit := g.HeadSizeLimit()

View File

@ -26,7 +26,7 @@ func createTestGroup(t *testing.T, headSizeLimit int64) *Group {
g, err := OpenGroup(headPath)
require.NoError(t, err, "Error opening Group")
g.SetHeadSizeLimit(headSizeLimit)
g.stopTicker()
g.ticker.Stop()
require.NotEqual(t, nil, g, "Failed to create Group")
return g
}