Skip to content

Commit

Permalink
Initial changes to make it usable a lib
Browse files Browse the repository at this point in the history
  • Loading branch information
zeisss committed Jan 29, 2015
1 parent c6a0c4c commit 99c499b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 52 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
retry-go
========

Small helper library to retry operations automatically on certain errors.

## Usage

```
retry.Do(someOp, retry.Timeout(15 * time.Second))
```

// The following options are supported:
// * RetryChecker(func(err error) bool) - If this func returns true for the returned error, the operation is tried again
// * MaxTries(int) - Maximum number of calls to op() before aborting with MaxRetriesReached
// * Timeout(time.Duration) - Maximum number of time to try to perform this op before aborting with TimeoutReached
// * Sleep(time.Duration) - time to sleep after error failed op()
//
55 changes: 55 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package retry

import (
"time"
)

type RetryOption func(options *retryOptions)

// Timeout specifies the maximum time that should be used before aborting the retry loop.
// Note that this does not abort the operation in progress.
func Timeout(d time.Duration) RetryOption {
return func(options *retryOptions) {
options.Timeout = d
}
}

// MaxTries specifies the maximum number of times op will be called by Do().
func MaxTries(tries int) RetryOption {
return func(options *retryOptions) {
options.MaxTries = tries
}
}

// RetryChecker defines whether the given error is an error that can be retried.
func RetryChecker(checker func(err error) bool) RetryOption {
return func(options *retryOptions) {
options.Checker = checker
}
}

func Sleep(d time.Duration) RetryOption {
return func(options *retryOptions) {
options.Sleep = d
}
}

type retryOptions struct {
Timeout time.Duration
MaxTries int
Checker func(err error) bool
Sleep time.Duration
}

func newRetryOptions(options ...RetryOption) retryOptions {
state := retryOptions{
Timeout: DefaultTimeout,
MaxTries: DefaultMaxTries,
Retryer: errgo.Any,
}

for _, option := range options {
option(&state)
}
return state
}
57 changes: 5 additions & 52 deletions retry.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package service
package retry

import (
"time"
Expand All @@ -16,58 +16,11 @@ var (
MaxRetriesReached = errgo.New("Operation aborted. To many errors.")
)

type retryOptions struct {
Timeout time.Duration
MaxTries int
Retryer func(err error) bool
Sleep time.Duration
}

type RetryOption func(options *retryOptions)

func RetryTimeout(d time.Duration) RetryOption {
return func(options *retryOptions) {
options.Timeout = d
}
}

func MaxTries(tries int) RetryOption {
return func(options *retryOptions) {
options.MaxTries = tries
}
}

// Retryer defines whether the given error is an error that can be retried.
func Retryer(retryer func(err error) bool) RetryOption {
return func(options *retryOptions) {
options.Retryer = retryer
}
}

func Sleep(d time.Duration) RetryOption {
return func(options *retryOptions) {
options.Sleep = d
}
}

func newRetryOptions(options ...RetryOption) retryOptions {
state := retryOptions{
Timeout: DefaultTimeout,
MaxTries: DefaultMaxTries,
Retryer: errgo.Any,
}

for _, option := range options {
option(&state)
}
return state
}

// retry performs the given operation. Based on the options, it can retry the operation,
// Do performs the given operation. Based on the options, it can retry the operation,
// if it failed.
//
// The following options are supported:
// * Retryer(func(err error) bool) - If this func returns true for the returned error, the operation is tried again
// * RetryChecker(func(err error) bool) - If this func returns true for the returned error, the operation is tried again
// * MaxTries(int) - Maximum number of calls to op() before aborting with MaxRetriesReached
// * Timeout(time.Duration) - Maximum number of time to try to perform this op before aborting with TimeoutReached
// * Sleep(time.Duration) - time to sleep after error failed op()
Expand All @@ -78,7 +31,7 @@ func newRetryOptions(options ...RetryOption) retryOptions {
// Retryer = errgo.Any
// Sleep = No sleep
//
func retry(op func() error, retryOptions ...RetryOption) error {
func Do(op func() error, retryOptions ...RetryOption) error {
options := newRetryOptions(retryOptions...)

timeout := time.After(options.Timeout)
Expand All @@ -96,7 +49,7 @@ func retry(op func() error, retryOptions ...RetryOption) error {
lastError := op()

if lastError != nil {
if options.Retryer != nil && options.Retryer(lastError) {
if options.Checker != nil && options.Checker(lastError) {
// Check max retries
if tryCounter >= options.MaxTries {
return errgo.WithCausef(lastError, MaxRetriesReached, "Tries %d > %d", tryCounter, options.MaxTries)
Expand Down

0 comments on commit 99c499b

Please sign in to comment.