From b470eb07b0b0e18ed51f1d3f5dc2d4c88d4ef1e1 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 07:30:27 -0600 Subject: [PATCH 01/12] Upgrade module version --- README.md | 4 ++++ go.mod | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2f03cc6..8347910 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ An expressive, flexible retry package for Go. [![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://godoc.org/go.coder.com/retry) +``` +go get github.com/coder/retry +``` + ## Features - Backoff helper diff --git a/go.mod b/go.mod index b5ddf5f..0b1e394 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,13 @@ -module go.coder.com/retry +module github.com/coder/retry/v2 + +go 1.17 require ( - github.com/davecgh/go-spew v1.1.0 // indirect github.com/pkg/errors v0.8.0 - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.1.4 ) + +require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect +) From 31e070a1d1ba201dcf8b5b6a4cdb42bbbfd03339 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 07:34:07 -0600 Subject: [PATCH 02/12] Remove Listener Remove the Listener implementation in the interest of doing one thing and doing it well. We can add it back in another package down the line. --- listener.go | 46 -------------------- listener_test.go | 110 ----------------------------------------------- 2 files changed, 156 deletions(-) delete mode 100644 listener.go delete mode 100644 listener_test.go diff --git a/listener.go b/listener.go deleted file mode 100644 index 2f2553f..0000000 --- a/listener.go +++ /dev/null @@ -1,46 +0,0 @@ -package retry - -import ( - "context" - "log" - "net" - "time" -) - -type Listener struct { - LogTmpErr func(err error) - net.Listener -} - -func (l Listener) Accept() (net.Conn, error) { - b := &Backoff{ - Floor: 5 * time.Millisecond, - Ceil: time.Second, - } - - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() - - for { - c, err := l.Listener.Accept() - if err == nil { - return c, nil - } - - ne, ok := err.(net.Error) - if !ok || !ne.Temporary() { - return nil, err - } - - if l.LogTmpErr == nil { - log.Printf("retry: temp error accepting next connection: %v", err) - } else { - l.LogTmpErr(err) - } - - err = b.Wait(ctx) - if err != nil { - return nil, err - } - } -} diff --git a/listener_test.go b/listener_test.go deleted file mode 100644 index 755f54d..0000000 --- a/listener_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package retry - -import ( - "net" - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/require" -) - - -type testListener struct { - acceptFn func() (net.Conn, error) -} - -func newTestListener(acceptFn func() (net.Conn, error)) net.Listener { - return &Listener{ - LogTmpErr: func(err error) {}, - Listener: &testListener{ - acceptFn: acceptFn, - }, - } -} - -func (l *testListener) Accept() (net.Conn, error) { - return l.acceptFn() -} - -func (l *testListener) Close() error { - panic("stub") -} - -func (l *testListener) Addr() net.Addr { - panic("stub") -} - -type testNetError struct { - temporary bool -} - -func (e *testNetError) Error() string { - return "test net error" -} - -func (e *testNetError) Temporary() bool { - return e.temporary -} - -func (e *testNetError) Timeout() bool { - panic("do not call") -} - -func TestListener(t *testing.T) { - t.Parallel() - t.Run("general error", func(t *testing.T) { - t.Parallel() - - expectedErr := errors.New("general error") - acceptFn := func() (net.Conn, error) { - return nil, expectedErr - } - - _, err := newTestListener(acceptFn).Accept() - require.Equal(t, expectedErr, err) - }) - t.Run("success", func(t *testing.T) { - t.Parallel() - - acceptFn := func() (net.Conn, error) { - return nil, nil - } - - _, err := newTestListener(acceptFn).Accept() - require.Nil(t, err) - }) - t.Run("non temp net error", func(t *testing.T) { - t.Parallel() - - expectedErr := &testNetError{false} - acceptFn := func() (net.Conn, error) { - return nil, expectedErr - } - - _, err := newTestListener(acceptFn).Accept() - require.Equal(t, expectedErr, err) - }) - t.Run("3x temp net error", func(t *testing.T) { - t.Parallel() - - callCount := 0 - acceptFn := func() (net.Conn, error) { - callCount++ - switch callCount { - case 1: - return nil, &testNetError{true} - case 2: - return nil, &testNetError{true} - case 3: - return nil, nil - default: - t.Fatalf("test listener called too many times; callCount: %v", callCount) - panic("unreachable") - } - } - - _, err := newTestListener(acceptFn).Accept() - require.Nil(t, err) - require.Equal(t, callCount, 3) - }) -} From b2f1f364e218a0c26df45b27387380009c802ff5 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 08:21:15 -0600 Subject: [PATCH 03/12] Update license year --- LICENSE | 2 +- backoff.go | 54 --------------------------------------------- backoff_test.go | 58 ------------------------------------------------- retrier.go | 1 + 4 files changed, 2 insertions(+), 113 deletions(-) delete mode 100644 backoff.go delete mode 100644 backoff_test.go create mode 100644 retrier.go diff --git a/LICENSE b/LICENSE index 71d81d0..717af18 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018 Coder Technologies Inc. +Copyright (c) 2021 Coder Technologies Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/backoff.go b/backoff.go deleted file mode 100644 index 518246c..0000000 --- a/backoff.go +++ /dev/null @@ -1,54 +0,0 @@ -package retry - -import ( - "context" - "time" - - "github.com/pkg/errors" -) - -// Backoff holds state about a backoff loop in which -// there should be a delay in iterations. -type Backoff struct { - // These two fields must be initialized. - // Floor should never be greater than or equal - // to the Ceil in general. If it is, the Backoff - // will stop backing off and just sleep for the Floor - // in Wait(). - Floor time.Duration - Ceil time.Duration - - delay time.Duration -} - -func (b *Backoff) backoff() { - if b.Floor >= b.Ceil { - return - } - - const growth = 2 - b.delay *= growth - if b.delay > b.Ceil { - b.delay = b.Ceil - } -} - -// Wait should be called at the end of the loop. It will sleep -// for the necessary duration before the next iteration of the loop -// can begin. -// If the context is cancelled, Wait will return early with a non-nil error. -func (b *Backoff) Wait(ctx context.Context) error { - if b.delay < b.Floor { - b.delay = b.Floor - } - - select { - case <-ctx.Done(): - return errors.Wrapf(ctx.Err(), "failed to sleep delay %v for retry attempt", b.delay) - case <-time.After(b.delay): - } - - b.backoff() - - return nil -} diff --git a/backoff_test.go b/backoff_test.go deleted file mode 100644 index da9c840..0000000 --- a/backoff_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package retry_test - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/require" - "go.coder.com/retry" -) - -func TestBackoff(t *testing.T) { - t.Parallel() - - t.Run("failure", func(t *testing.T) { - t.Parallel() - - start := time.Now() - - b := &retry.Backoff{ - Floor: time.Millisecond, - Ceil: time.Second * 5, - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, time.Millisecond*100) - defer cancel() - - for time.Since(start) < time.Second { - err := b.Wait(ctx) - if err != nil { - return - } - } - - t.Errorf("succeeded: took: %v", time.Since(start)) - }) - - t.Run("success", func(t *testing.T) { - t.Parallel() - - start := time.Now() - - b := &retry.Backoff{ - Floor: time.Millisecond, - Ceil: time.Second * 5, - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, time.Second*2) - defer cancel() - - for time.Since(start) < time.Second { - err := b.Wait(ctx) - require.NoError(t, err, "took: %v", time.Since(start)) - } - }) -} diff --git a/retrier.go b/retrier.go new file mode 100644 index 0000000..8bc36c9 --- /dev/null +++ b/retrier.go @@ -0,0 +1 @@ +package retry From 6c488e9722eb258b0d6205e3eba5cd082dbc7b2a Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 08:36:33 -0600 Subject: [PATCH 04/12] Finish refactor --- README.md | 34 +++++++++++++++----- doc.go | 2 +- go.mod | 2 +- retrier.go | 51 +++++++++++++++++++++++++++++ retrier_test.go | 48 ++++++++++++++++++++++++++++ retry_example_test.go | 74 ------------------------------------------- 6 files changed, 127 insertions(+), 84 deletions(-) create mode 100644 retrier_test.go delete mode 100644 retry_example_test.go diff --git a/README.md b/README.md index 8347910..e4f5276 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,39 @@ An expressive, flexible retry package for Go. -[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://godoc.org/go.coder.com/retry) +[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://godoc.org/github.com/coder/retry) ``` go get github.com/coder/retry ``` ## Features - -- Backoff helper -- Retrying net.Listener wrapper +- For loop experience instead of closures +- Only 4 exported methods ## Examples -See [retry_example_test.go](retry_example_test.go) - -## We're Hiring! +Wait for connectivity to google.com, checking at most once every +second. +```go +func pingGoogle(ctx context.Context) error { + r := retry.New(time.Second, time.Second*10) + for r.Wait(ctx) { + _, err := http.Get("https://google.com") + r.SetError(err) + } + return r.Error() +} +``` -If you're a passionate Go developer, send your resume and/or GitHub link to [jobs@coder.com](mailto:jobs@coder.com). +Wait for connectivity to google.com, checking at most 10 times. +```go +func pingGoogle(ctx context.Context) error { + r := retry.New(time.Second, time.Second*10) + for n := 0; r.Wait(ctx) && n < 10; n++ { + _, err := http.Get("https://google.com") + r.SetError(err) + } + return r.Error() +} +``` \ No newline at end of file diff --git a/doc.go b/doc.go index 591ed4e..8d01b39 100644 --- a/doc.go +++ b/doc.go @@ -1,2 +1,2 @@ -// Package retry contains utilities for retrying an action until it succeeds. +// Package retry runs a failable function until it succeeds. package retry diff --git a/go.mod b/go.mod index 0b1e394..18975d9 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/coder/retry/v2 +module github.com/coder/retry go 1.17 diff --git a/retrier.go b/retrier.go index 8bc36c9..95e2ade 100644 --- a/retrier.go +++ b/retrier.go @@ -1 +1,52 @@ package retry + +import ( + "context" + "time" +) + +// Retrier represents a retry instance. +// Use New instead of creating this object directly. +type Retrier struct { + delay time.Duration + floor, ceil time.Duration + err *error +} + +// New creates an exponential backoff retrier that backs off from floor to ceil duration. +func New(floor, ceil time.Duration) *Retrier { + return &Retrier{ + delay: floor, + floor: floor, + ceil: ceil, + } +} + +func (r *Retrier) Wait(ctx context.Context) bool { + if r.err != nil && *r.err == nil { + // We've succeeded! + return false + } + const growth = 2 + r.delay *= growth + if r.delay > r.ceil { + r.delay = r.ceil + } + select { + case <-time.After(r.delay): + return true + case <-ctx.Done(): + return false + } +} + +func (r *Retrier) SetError(err error) { + r.err = &err +} + +func (r *Retrier) Error() error { + if r.err == nil { + return nil + } + return *r.err +} diff --git a/retrier_test.go b/retrier_test.go new file mode 100644 index 0000000..24c8785 --- /dev/null +++ b/retrier_test.go @@ -0,0 +1,48 @@ +package retry + +import ( + "context" + "fmt" + "io" + "testing" + "time" +) + +func TestContextCancel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + r := New(time.Hour, time.Hour) + for r.Wait(ctx) { + t.Fatalf("attempt allowed even though context cancelled") + } +} + +func TestError1(t *testing.T) { + r := New(time.Millisecond, time.Millisecond*10) + var n int + for ; r.Wait(context.Background()); n++ { + if n < 9 { + r.SetError(fmt.Errorf("n is too small")) + continue + } + r.SetError(nil) + } + if n != 10 { + t.Fatalf("expected n == 10, but n == %v", n) + } +} + +func TestError2(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*10) + defer cancel() + + r := New(time.Millisecond, time.Millisecond*10) + var n int + for ; r.Wait(ctx); n++ { + r.SetError(io.EOF) + } + if r.Error() != io.EOF { + t.Fatalf("expected error %v but got %v", io.EOF, r.Error()) + } +} diff --git a/retry_example_test.go b/retry_example_test.go deleted file mode 100644 index a334e4d..0000000 --- a/retry_example_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package retry_test - -import ( - "context" - "log" - "net" - "time" - - "go.coder.com/retry" -) - -func ExampleBackoffSuccess() { - start := time.Now() - - b := &retry.Backoff{ - Floor: time.Millisecond, - Ceil: time.Second * 5, - } - - ctx := context.Background() - - for time.Since(start) < time.Second { - err := b.Wait(ctx) - if err != nil { - log.Fatalf("failed: took: %v: err: %v", time.Since(start), err) - } - } - - log.Printf("success: took: %v", time.Since(start)) -} - -func ExampleBackoffError() { - start := time.Now() - - b := &retry.Backoff{ - Floor: time.Millisecond, - Ceil: time.Second * 5, - } - - ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, time.Millisecond*100) - defer cancel() - - for time.Since(start) < time.Second { - err := b.Wait(ctx) - if err != nil { - log.Fatalf("failed: took: %v: err: %v", time.Since(start), err) - } - } - - log.Printf("success: took: %v", time.Since(start)) -} - -func ExampleListener() { - l, err := net.Listen("tcp", "localhost:0") - if err != nil { - log.Fatalf("failed to listen: %v", err) - } - defer l.Close() - - l = retry.Listener{ - Listener: l, - } - - for { - c, err := l.Accept() - if err != nil { - log.Fatalf("failed to accept: %v", err) - } - defer c.Close() - - // ... - } -} From a2f4222487523d4beaa1b74a4a72324b710ece5c Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 08:37:53 -0600 Subject: [PATCH 05/12] Remove ALL dependencies --- README.md | 1 + go.mod | 10 ---------- go.sum | 8 -------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/README.md b/README.md index e4f5276..738c122 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ go get github.com/coder/retry ## Features - For loop experience instead of closures - Only 4 exported methods +- No external dependencies ## Examples diff --git a/go.mod b/go.mod index 18975d9..12a1d62 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,3 @@ module github.com/coder/retry go 1.17 - -require ( - github.com/pkg/errors v0.8.0 - github.com/stretchr/testify v1.1.4 -) - -require ( - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect -) diff --git a/go.sum b/go.sum index 7fed76a..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.1.4 h1:ToftOQTytwshuOSj6bDSolVUa3GINfJP/fg3OkkOzQQ= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= From b59fe263c0c2c546fa060916e29c49e979d424a0 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 08:38:51 -0600 Subject: [PATCH 06/12] Clean English --- retrier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retrier.go b/retrier.go index 95e2ade..c1781e4 100644 --- a/retrier.go +++ b/retrier.go @@ -13,7 +13,7 @@ type Retrier struct { err *error } -// New creates an exponential backoff retrier that backs off from floor to ceil duration. +// New creates a retrier that exponentially backs off from floor to ceil pauses. func New(floor, ceil time.Duration) *Retrier { return &Retrier{ delay: floor, From 723e29f2f693ac0dc25ab2aa7f69d5b1bd72e632 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 08:39:26 -0600 Subject: [PATCH 07/12] Improve minor code formatting --- retrier.go | 1 + 1 file changed, 1 insertion(+) diff --git a/retrier.go b/retrier.go index c1781e4..0ff94ac 100644 --- a/retrier.go +++ b/retrier.go @@ -27,6 +27,7 @@ func (r *Retrier) Wait(ctx context.Context) bool { // We've succeeded! return false } + const growth = 2 r.delay *= growth if r.delay > r.ceil { From 94fab55a23f0eda3116ac065acaf52aa3d80f2ed Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 08:41:05 -0600 Subject: [PATCH 08/12] Another minor English improvement --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 738c122..a4cd659 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # retry -An expressive, flexible retry package for Go. +A small retry package for Go. [![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://godoc.org/github.com/coder/retry) From 767eb4f7ed45ffbeb0898e08cb539e7bba80bdc8 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 09:34:22 -0600 Subject: [PATCH 09/12] Remove error nonsense We can always add it back later. --- README.md | 24 ++++++++++++++++-------- retrier.go | 13 +------------ retrier_test.go | 31 ------------------------------- 3 files changed, 17 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index a4cd659..4fa3c53 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ go get github.com/coder/retry ## Features - For loop experience instead of closures -- Only 4 exported methods +- Only 2 exported methods - No external dependencies ## Examples @@ -19,23 +19,31 @@ Wait for connectivity to google.com, checking at most once every second. ```go func pingGoogle(ctx context.Context) error { + var err error r := retry.New(time.Second, time.Second*10) for r.Wait(ctx) { - _, err := http.Get("https://google.com") - r.SetError(err) + _, err = http.Get("https://google.com") + if err != nil { + continue + } + break } - return r.Error() + return err } ``` Wait for connectivity to google.com, checking at most 10 times. ```go func pingGoogle(ctx context.Context) error { + var err error r := retry.New(time.Second, time.Second*10) for n := 0; r.Wait(ctx) && n < 10; n++ { - _, err := http.Get("https://google.com") - r.SetError(err) - } - return r.Error() + _, err = http.Get("https://google.com") + if err != nil { + continue + } + break + } + return err } ``` \ No newline at end of file diff --git a/retrier.go b/retrier.go index 0ff94ac..c785d73 100644 --- a/retrier.go +++ b/retrier.go @@ -5,7 +5,7 @@ import ( "time" ) -// Retrier represents a retry instance. +// Retrier implements an exponentially backing off retry instance. // Use New instead of creating this object directly. type Retrier struct { delay time.Duration @@ -40,14 +40,3 @@ func (r *Retrier) Wait(ctx context.Context) bool { return false } } - -func (r *Retrier) SetError(err error) { - r.err = &err -} - -func (r *Retrier) Error() error { - if r.err == nil { - return nil - } - return *r.err -} diff --git a/retrier_test.go b/retrier_test.go index 24c8785..c6ac1e7 100644 --- a/retrier_test.go +++ b/retrier_test.go @@ -2,8 +2,6 @@ package retry import ( "context" - "fmt" - "io" "testing" "time" ) @@ -17,32 +15,3 @@ func TestContextCancel(t *testing.T) { t.Fatalf("attempt allowed even though context cancelled") } } - -func TestError1(t *testing.T) { - r := New(time.Millisecond, time.Millisecond*10) - var n int - for ; r.Wait(context.Background()); n++ { - if n < 9 { - r.SetError(fmt.Errorf("n is too small")) - continue - } - r.SetError(nil) - } - if n != 10 { - t.Fatalf("expected n == 10, but n == %v", n) - } -} - -func TestError2(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*10) - defer cancel() - - r := New(time.Millisecond, time.Millisecond*10) - var n int - for ; r.Wait(ctx); n++ { - r.SetError(io.EOF) - } - if r.Error() != io.EOF { - t.Fatalf("expected error %v but got %v", io.EOF, r.Error()) - } -} From 98056d89b24211941a64eecb8837883e6ef79216 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 09:36:48 -0600 Subject: [PATCH 10/12] Clean english --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4fa3c53..c561682 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # retry -A small retry package for Go. +An exponentially backing off retry package for Go. [![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://godoc.org/github.com/coder/retry) @@ -9,7 +9,7 @@ go get github.com/coder/retry ``` ## Features -- For loop experience instead of closures +- Offers a `for` loop experience instead of closures - Only 2 exported methods - No external dependencies From e3b5d86ad8aa6f7226e51aa4cb36466bbdf041fa Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 09:53:13 -0600 Subject: [PATCH 11/12] Formatting? --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c561682..568af6b 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ func pingGoogle(ctx context.Context) error { r := retry.New(time.Second, time.Second*10) for r.Wait(ctx) { _, err = http.Get("https://google.com") - if err != nil { + if err != nil { continue } break From 90c791f6dbdc208536b3bde2ad29d664aecf36ab Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 16 Dec 2021 09:53:50 -0600 Subject: [PATCH 12/12] Remove error vestiges --- retrier.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/retrier.go b/retrier.go index c785d73..cfcbe7d 100644 --- a/retrier.go +++ b/retrier.go @@ -10,7 +10,6 @@ import ( type Retrier struct { delay time.Duration floor, ceil time.Duration - err *error } // New creates a retrier that exponentially backs off from floor to ceil pauses. @@ -23,11 +22,6 @@ func New(floor, ceil time.Duration) *Retrier { } func (r *Retrier) Wait(ctx context.Context) bool { - if r.err != nil && *r.err == nil { - // We've succeeded! - return false - } - const growth = 2 r.delay *= growth if r.delay > r.ceil {