Skip to content

Commit

Permalink
Merge pull request #12 from sjanota/delay-type
Browse files Browse the repository at this point in the history
Allow to configure fixed or back off delay
  • Loading branch information
JaSei authored Jan 11, 2019
2 parents 7e26136 + 4b5b36d commit 48dfe71
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 9 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,33 @@ now implement via functions produces Options (aka `retry.OnRetry`)

## Usage

#### func BackOffDelay

```go
func BackOffDelay(n uint, config *config) time.Duration
```
BackOffDelay is a DelayType which increases delay between consecutive retries

#### func Do

```go
func Do(retryableFunc RetryableFunc, opts ...Option) error
```

#### func FixedDelay

```go
func FixedDelay(_ uint, config *config) time.Duration
```
FixedDelay is a DelayType which keeps delay the same through all iterations

#### type DelayTypeFunc

```go
type DelayTypeFunc func(n uint, config *config) time.Duration
```


#### type Error

```go
Expand Down Expand Up @@ -144,6 +165,13 @@ func Delay(delay time.Duration) Option
```
Delay set delay between retry default is 100ms

#### func DelayType

```go
func DelayType(delayType DelayTypeFunc) Option
```
DelayType set type of the delay between retries default is BackOff

#### func OnRetry

```go
Expand Down
29 changes: 25 additions & 4 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ type RetryIfFunc func(error) bool
// n = count of attempts
type OnRetryFunc func(n uint, err error)

type DelayTypeFunc func(n uint, config *config) time.Duration

type config struct {
attempts uint
delay time.Duration
onRetry OnRetryFunc
retryIf RetryIfFunc
attempts uint
delay time.Duration
onRetry OnRetryFunc
retryIf RetryIfFunc
delayType DelayTypeFunc
}

// Option represents an option for retry.
Expand All @@ -37,6 +40,24 @@ func Delay(delay time.Duration) Option {
}
}

// DelayType set type of the delay between retries
// default is BackOff
func DelayType(delayType DelayTypeFunc) Option {
return func(c *config) {
c.delayType = delayType
}
}

// BackOffDelay is a DelayType which increases delay between consecutive retries
func BackOffDelay(n uint, config *config) time.Duration {
return config.delay * (1 << (n - 1))
}

// FixedDelay is a DelayType which keeps delay the same through all iterations
func FixedDelay(_ uint, config *config) time.Duration {
return config.delay
}

// OnRetry function callback are called each retry
//
// log each retry example:
Expand Down
11 changes: 6 additions & 5 deletions retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error {

//default
config := &config{
attempts: 10,
delay: 100 * time.Millisecond,
onRetry: func(n uint, err error) {},
retryIf: func(err error) bool { return true },
attempts: 10,
delay: 100 * time.Millisecond,
onRetry: func(n uint, err error) {},
retryIf: func(err error) bool { return true },
delayType: BackOffDelay,
}

//apply opts
Expand All @@ -107,7 +108,7 @@ func Do(retryableFunc RetryableFunc, opts ...Option) error {
break
}

delayTime := config.delay * (1 << (n - 1))
delayTime := config.delayType(n, config)
time.Sleep(delayTime)
} else {
return nil
Expand Down
12 changes: 12 additions & 0 deletions retry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,15 @@ func TestDefaultSleep(t *testing.T) {
assert.Error(t, err)
assert.True(t, dur > 10*time.Millisecond, "3 times default retry is longer then 10ms")
}

func TestFixedSleep(t *testing.T) {
start := time.Now()
err := Do(
func() error { return errors.New("test") },
Attempts(3),
DelayType(FixedDelay),
)
dur := time.Since(start)
assert.Error(t, err)
assert.True(t, dur < 500*time.Millisecond, "3 times default retry is shorter then 500ms")
}

0 comments on commit 48dfe71

Please sign in to comment.