mirror of https://github.com/status-im/consul.git
sdk/retry: remove the need to pass args to NextOr
This commit is contained in:
parent
c932833acb
commit
034c5c5f8c
|
@ -120,15 +120,7 @@ func dedup(a []string) string {
|
||||||
func run(r Retryer, t Failer, f func(r *R)) {
|
func run(r Retryer, t Failer, f func(r *R)) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
rr := &R{}
|
rr := &R{}
|
||||||
fail := func() {
|
for r.Continue() {
|
||||||
t.Helper()
|
|
||||||
out := dedup(rr.output)
|
|
||||||
if out != "" {
|
|
||||||
t.Log(out)
|
|
||||||
}
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
for r.NextOr(t, fail) {
|
|
||||||
func() {
|
func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if p := recover(); p != nil && p != runFailed {
|
if p := recover(); p != nil && p != runFailed {
|
||||||
|
@ -142,6 +134,12 @@ func run(r Retryer, t Failer, f func(r *R)) {
|
||||||
}
|
}
|
||||||
rr.fail = false
|
rr.fail = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out := dedup(rr.output)
|
||||||
|
if out != "" {
|
||||||
|
t.Log(out)
|
||||||
|
}
|
||||||
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultFailer provides default retry.Run() behavior for unit tests.
|
// DefaultFailer provides default retry.Run() behavior for unit tests.
|
||||||
|
@ -162,9 +160,9 @@ func ThreeTimes() *Counter {
|
||||||
// Retryer provides an interface for repeating operations
|
// Retryer provides an interface for repeating operations
|
||||||
// until they succeed or an exit condition is met.
|
// until they succeed or an exit condition is met.
|
||||||
type Retryer interface {
|
type Retryer interface {
|
||||||
// NextOr returns true if the operation should be repeated.
|
// NextOr returns true if the operation should be repeated, otherwise it
|
||||||
// Otherwise, it calls fail and returns false.
|
// returns false to indicate retrying should stop.
|
||||||
NextOr(t Failer, fail func()) bool
|
Continue() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counter repeats an operation a given number of
|
// Counter repeats an operation a given number of
|
||||||
|
@ -176,10 +174,8 @@ type Counter struct {
|
||||||
count int
|
count int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Counter) NextOr(t Failer, fail func()) bool {
|
func (r *Counter) Continue() bool {
|
||||||
t.Helper()
|
|
||||||
if r.count == r.Count {
|
if r.count == r.Count {
|
||||||
fail()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if r.count > 0 {
|
if r.count > 0 {
|
||||||
|
@ -200,14 +196,12 @@ type Timer struct {
|
||||||
stop time.Time
|
stop time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Timer) NextOr(t Failer, fail func()) bool {
|
func (r *Timer) Continue() bool {
|
||||||
t.Helper()
|
|
||||||
if r.stop.IsZero() {
|
if r.stop.IsZero() {
|
||||||
r.stop = time.Now().Add(r.Timeout)
|
r.stop = time.Now().Add(r.Timeout)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if time.Now().After(r.stop) {
|
if time.Now().After(r.stop) {
|
||||||
fail()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
time.Sleep(r.Wait)
|
time.Sleep(r.Wait)
|
||||||
|
|
|
@ -3,6 +3,8 @@ package retry
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// delta defines the time band a test run should complete in.
|
// delta defines the time band a test run should complete in.
|
||||||
|
@ -19,19 +21,15 @@ func TestRetryer(t *testing.T) {
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
var iters, fails int
|
var iters int
|
||||||
fail := func() { fails++ }
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
for tt.r.NextOr(t, fail) {
|
for tt.r.Continue() {
|
||||||
iters++
|
iters++
|
||||||
}
|
}
|
||||||
dur := time.Since(start)
|
dur := time.Since(start)
|
||||||
if got, want := iters, 3; got != want {
|
if got, want := iters, 3; got != want {
|
||||||
t.Fatalf("got %d retries want %d", got, want)
|
t.Fatalf("got %d retries want %d", got, want)
|
||||||
}
|
}
|
||||||
if got, want := fails, 1; got != want {
|
|
||||||
t.Fatalf("got %d FailNow calls want %d", got, want)
|
|
||||||
}
|
|
||||||
// since the first iteration happens immediately
|
// since the first iteration happens immediately
|
||||||
// the retryer waits only twice for three iterations.
|
// the retryer waits only twice for three iterations.
|
||||||
// order of events: (true, (wait) true, (wait) true, false)
|
// order of events: (true, (wait) true, (wait) true, false)
|
||||||
|
@ -41,3 +39,32 @@ func TestRetryer(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunWith(t *testing.T) {
|
||||||
|
t.Run("calls FailNow after exceeding retries", func(t *testing.T) {
|
||||||
|
ft := &fakeT{}
|
||||||
|
iter := 0
|
||||||
|
RunWith(&Counter{Count: 3, Wait: time.Millisecond}, ft, func(r *R) {
|
||||||
|
iter++
|
||||||
|
r.FailNow()
|
||||||
|
})
|
||||||
|
|
||||||
|
require.Equal(t, 3, iter)
|
||||||
|
require.Equal(t, 1, ft.fails)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeT struct {
|
||||||
|
fails int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeT) Helper() {}
|
||||||
|
|
||||||
|
func (f *fakeT) Log(args ...interface{}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeT) FailNow() {
|
||||||
|
f.fails++
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Failer = &fakeT{}
|
||||||
|
|
Loading…
Reference in New Issue