Skip to content

Fix deadlock when stopping on non-empty file/buffer #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions tail.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func TailFile(filename string, config Config) (*Tail, error) {
return t, nil
}

// Return the file's current position, like stdio's ftell().
// Tell returns the file's current position, like stdio's ftell().
// But this value is not very accurate.
// One line from the chan(tail.Lines) may have been read,
// so it may have lost one line.
Expand Down Expand Up @@ -355,10 +355,9 @@ func (tail *Tail) waitForChanges() error {
tail.Logger.Printf("Successfully reopened %s", tail.Filename)
tail.openReader()
return nil
} else {
tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
return ErrStop
}
tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
return ErrStop
case <-tail.changes.Truncated:
// Always reopen truncated files (Follow is true)
tail.Logger.Printf("Re-opening truncated file %s ...", tail.Filename)
Expand All @@ -371,7 +370,6 @@ func (tail *Tail) waitForChanges() error {
case <-tail.Dying():
return ErrStop
}
panic("unreachable")
}

func (tail *Tail) openReader() {
Expand Down Expand Up @@ -412,7 +410,11 @@ func (tail *Tail) sendLine(line string) bool {

for _, line := range lines {
tail.lineNum++
tail.Lines <- &Line{line, tail.lineNum, now, nil}
select {
case tail.Lines <- &Line{line, tail.lineNum, now, nil}:
case <-tail.Dying():
return true
}
}

if tail.Config.RateLimiter != nil {
Expand Down
16 changes: 12 additions & 4 deletions tail_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ func TestStop(t *testing.T) {
tail.Cleanup()
}

func TestStopNonEmptyFile(t *testing.T) {
tailTest := NewTailTest("maxlinesize", t)
tailTest.CreateFile("test.txt", "hello\nthere\nworld\n")
tail := tailTest.StartTail("test.txt", Config{})
tail.Stop()
tail.Cleanup()
// success here is if it doesn't panic.
}

func TestStopAtEOF(t *testing.T) {
tailTest := NewTailTest("maxlinesize", t)
tailTest.CreateFile("test.txt", "hello\nthere\nworld\n")
Expand Down Expand Up @@ -330,7 +339,7 @@ func TestTell(t *testing.T) {
Follow: false,
Location: &SeekInfo{0, io.SeekStart}}
tail := tailTest.StartTail("test.txt", config)
// read noe line
// read one line
line := <-tail.Lines
if line.Num != 1 {
tailTest.Errorf("expected line to have number 1 but got %d", line.Num)
Expand All @@ -339,8 +348,7 @@ func TestTell(t *testing.T) {
if err != nil {
tailTest.Errorf("Tell return error: %s", err.Error())
}
tail.Done()
// tail.close()
tail.Stop()

config = Config{
Follow: false,
Expand All @@ -359,7 +367,7 @@ func TestTell(t *testing.T) {
break
}
tailTest.RemoveFile("test.txt")
tail.Done()
tail.Stop()
tail.Cleanup()
}

Expand Down