Skip to content
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

Fix backoff error never logged after a success #42

Merged
merged 2 commits into from
Jun 6, 2017
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: 11 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions backoff/backoff.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type backoff struct {
// each iterations. If it hits an error, it exponentially backs
// off to maxBackoff. Backoff will log when it backs off, but
// will stop logging when it reaches maxBackoff. It will also
// log on first success.
// log on first success in the beginning and after errors.
type Interface interface {
Start()
Stop()
Expand Down Expand Up @@ -65,12 +65,13 @@ func (b *backoff) Start() {

if err != nil {
backoff *= 2
shouldLog = true
if backoff > b.maxBackoff {
backoff = b.maxBackoff
shouldLog = false
}
} else if backoff > b.initialBackoff {
} else {
backoff = b.initialBackoff
shouldLog = true
}

if shouldLog {
Expand All @@ -82,9 +83,9 @@ func (b *backoff) Start() {
}
}

if backoff >= b.maxBackoff || err == nil {
shouldLog = false
}
// Re-enable logging if we came from an error (suppressed or not)
// since we want to log in case a success follows.
shouldLog = err != nil

select {
case <-time.After(backoff):
Expand Down
56 changes: 56 additions & 0 deletions backoff/backoff_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package backoff_test

import (
"errors"
"testing"
"time"

log "github.com/Sirupsen/logrus"
"github.com/Sirupsen/logrus/hooks/test"
"github.com/weaveworks/common/backoff"
)

func TestLog(t *testing.T) {
hook := test.NewGlobal()

err := errors.New("sample")
cases := []struct {
returns []error
expectedLastLevel log.Level
expectedCount int
}{
{[]error{nil}, log.InfoLevel, 1},
{[]error{nil, nil /*x*/}, log.InfoLevel, 1},
{[]error{nil, err}, log.WarnLevel, 2},
{[]error{nil, err, nil}, log.InfoLevel, 3},
{[]error{nil, err, nil, nil /*x*/}, log.InfoLevel, 3},
{[]error{nil, err}, log.WarnLevel, 2},
{[]error{nil, err, err}, log.WarnLevel, 3},
{[]error{nil, err, err, err /*x*/}, log.WarnLevel, 3},
{[]error{nil, err, err, err /*x*/, nil}, log.InfoLevel, 4},
}

for ci, c := range cases {
hook.Reset()

ri := 0
bo := backoff.New(func() (done bool, err error) {
if ri >= len(c.returns) {
done, err = true, nil // abort
} else {
done, err = false, c.returns[ri]
}
ri++
return
}, "test")
bo.SetInitialBackoff(1 * time.Millisecond)
bo.SetMaxBackoff(4 * time.Millisecond) // exceeded at 3rd consecutive error
bo.Start()

if len(hook.Entries) != c.expectedCount {
t.Errorf("case #%d failed: expected log count %d but got %d", ci, c.expectedCount, len(hook.Entries))
} else if hook.LastEntry().Level != c.expectedLastLevel {
t.Errorf("case #%d failed: expected level %d but got %d", ci, c.expectedLastLevel, hook.LastEntry().Level)
}
}
}