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

Return value #92

Closed
wants to merge 2 commits into from
Closed
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
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
module github.com/avast/retry-go/v4

go 1.13
go 1.18

require github.com/stretchr/testify v1.8.1

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
48 changes: 25 additions & 23 deletions retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ import (
)

// Function signature of retryable function
type RetryableFunc func() error
type RetryableFunc func() (any, error)

// Default timer is a wrapper around time.After
type timerImpl struct{}
Expand All @@ -79,7 +79,7 @@ func (t *timerImpl) After(d time.Duration) <-chan time.Time {
return time.After(d)
}

func Do(retryableFunc RetryableFunc, opts ...Option) error {
func Do(retryableFunc RetryableFunc, opts ...Option) (any, error) {
var n uint

// default
Expand All @@ -91,27 +91,29 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error {
}

if err := config.context.Err(); err != nil {
return err
return nil, err
}

// Setting attempts to 0 means we'll retry until we succeed
if config.attempts == 0 {
for err := retryableFunc(); err != nil; err = retryableFunc() {
n++

if !IsRecoverable(err) {
return err
}

config.onRetry(n, err)
select {
case <-config.timer.After(delay(config, n, err)):
case <-config.context.Done():
return config.context.Err()
for true {
value, err := retryableFunc()
if err != nil {
n++
if !IsRecoverable(err) {
return nil, err
}
config.onRetry(n, err)
config.onRetry(n, err)
select {
case <-config.timer.After(delay(config, n, err)):
case <-config.context.Done():
return nil, config.context.Err()
}
} else {
return value, nil
}
}

return nil
}

var errorLog Error
Expand All @@ -129,7 +131,7 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error {
lastErrIndex := n
shouldRetry := true
for shouldRetry {
err := retryableFunc()
value, err := retryableFunc()

if err != nil {
errorLog[lastErrIndex] = unpackUnrecoverable(err)
Expand Down Expand Up @@ -157,15 +159,15 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error {
case <-config.timer.After(delay(config, n, err)):
case <-config.context.Done():
if config.lastErrorOnly {
return config.context.Err()
return nil, config.context.Err()
}
n++
errorLog[n] = config.context.Err()
return errorLog[:lenWithoutNil(errorLog)]
return nil, errorLog[:lenWithoutNil(errorLog)]
}

} else {
return nil
return value, nil
}

n++
Expand All @@ -177,9 +179,9 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error {
}

if config.lastErrorOnly {
return errorLog[lastErrIndex]
return nil, errorLog[lastErrIndex]
}
return errorLog[:lenWithoutNil(errorLog)]
return nil, errorLog[:lenWithoutNil(errorLog)]
}

func newDefaultRetryConfig() *Config {
Expand Down
Loading