Golang retry library.
Retry - small library, that provides api for easy function retry and error handling. Package has some benefits unlike known implementations:
- laconic api
- rich retry strategy set
- easy customization
- context package support
Retry function until success:
_ = retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
})
Limit attempts:
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.MaxAttempts(10))
Delay between retries:
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.FixedDelay(time.Second))
Combine few retry strategies:
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.MaxAttempts(10), retry.FixedDelay(time.Second))
Breaking retry loop directly from function:
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
if !canRetry {
return retry.Unrecoverable(err)
}
return err
})
Using context:
err := retry.ExecContext(ctx, func(ctx context.Context, retryNumber int) (err error) {
// your logic here
return err
})
Context cancellation:
ctx, cancel := context.WithCancel(context.Background())
go func() {
// wait some event
cancel()
}()
err := retry.ExecContext(ctx, func(ctx context.Context, retryNumber int) (err error) {
// your logic here
return err
})
Be careful:
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.MaxAttempts(2), retry.FixedDelay(time.Second))
not similar to
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.FixedDelay(time.Second), retry.MaxAttempts(2))
Trace steps in the first case are:
- Function call
- Max attempts check
- Delay
- Function call
- Max attempts check
- Break loop
Trace steps in the second case are:
- Function call
- Delay
- Max attempts check
- Function call
- Delay
- Max attempts check
- Break loop
So, we can see, that second block of code will have unnecessary delay. It is highly recommended to store strategies, that limit attempts, before strategies, that do delays.
Some strategies have internal state, so it is highly recommended not to share strategies between several Exec
calls.
Incorrect:
strategy := retry.MaxAttempts(2)
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, strategy)
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, strategy)
Correct:
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.MaxAttempts(2))
err := retry.Exec(func(retryNumber int) (err error) {
// your logic here
return err
}, retry.MaxAttempts(2))
Retry is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
- Email:
cherkashin.evgeny.viktorovich@gmail.com
- Telegram:
@evgeny_cherkashin