Browse Source

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
pull/2135/head
Anton Kaliaev 6 years ago
parent
commit
b33f73eaf1
No known key found for this signature in database GPG Key ID: 7B6881D965918214
3 changed files with 20 additions and 24 deletions
  1. +15
    -13
      libs/autofile/autofile.go
  2. +4
    -10
      libs/autofile/group.go
  3. +1
    -1
      libs/autofile/group_test.go

+ 15
- 13
libs/autofile/autofile.go 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
}
}


+ 4
- 10
libs/autofile/group.go 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()


+ 1
- 1
libs/autofile/group_test.go 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
}


Loading…
Cancel
Save