Skip to content

Commit

Permalink
Ensure that the millRun goroutine terminates when Close called.
Browse files Browse the repository at this point in the history
Currently the millRun goroutines leaks. This is very noticable if
a Logger is constructed periodically, used and then closed.

This change ensures that the millCh channel is closed if it exists.
  • Loading branch information
howbazaar committed Mar 26, 2020
1 parent 94d9e49 commit 10710b3
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions lumberjack.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ type Logger struct {
file *os.File
mu sync.Mutex

millCh chan bool
startMill sync.Once
millCh chan struct{}
}

var (
Expand Down Expand Up @@ -175,6 +174,10 @@ func (l *Logger) close() error {
}
err := l.file.Close()
l.file = nil
if l.millCh != nil {
close(l.millCh)
l.millCh = nil
}
return err
}

Expand Down Expand Up @@ -375,8 +378,8 @@ func (l *Logger) millRunOnce() error {

// millRun runs in a goroutine to manage post-rotation compression and removal
// of old log files.
func (l *Logger) millRun() {
for _ = range l.millCh {
func (l *Logger) millRun(ch <-chan struct{}) {
for range ch {
// what am I going to do, log this?
_ = l.millRunOnce()
}
Expand All @@ -385,12 +388,13 @@ func (l *Logger) millRun() {
// mill performs post-rotation compression and removal of stale log files,
// starting the mill goroutine if necessary.
func (l *Logger) mill() {
l.startMill.Do(func() {
l.millCh = make(chan bool, 1)
go l.millRun()
})
// It is safe to check the millCh here as we are inside the mutex lock.
if l.millCh == nil {
l.millCh = make(chan struct{}, 1)
go l.millRun(l.millCh)
}
select {
case l.millCh <- true:
case l.millCh <- struct{}{}:
default:
}
}
Expand Down

0 comments on commit 10710b3

Please sign in to comment.