-
Notifications
You must be signed in to change notification settings - Fork 0
/
retrier.go
142 lines (132 loc) · 5.11 KB
/
retrier.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package retrier
import (
"time"
"github.com/hueristiq/hq-go-retrier/backoff"
)
// Configuration holds the settings for retry operations. These settings determine the behavior
// of the retry mechanism, such as the number of retries, delay between retries, and the backoff
// strategy to be used.
//
// Fields:
// - maxRetries: The maximum number of retry attempts allowed before giving up.
// - minDelay: The minimum delay between retries.
// - maxDelay: The maximum allowable delay between retries.
// - backoff: A function that calculates the backoff duration based on retry attempt number and delay limits.
// - notifier: A callback function that gets triggered on each retry attempt, providing feedback on errors and backoff duration.
type Configuration struct {
maxRetries int
minDelay time.Duration
maxDelay time.Duration
backoff backoff.Backoff
notifier Notifer
}
// Notifer is a callback function type used to handle notifications during retry attempts.
// This function is invoked on every retry attempt, providing details about the error that
// triggered the retry and the calculated backoff duration before the next attempt.
//
// Parameters:
// - err: The error encountered in the current retry attempt.
// - backoff: The duration of backoff calculated before the next retry attempt.
//
// Example:
//
// func logNotifier(err error, backoff time.Duration) {
// fmt.Printf("Retrying after error: %v, backoff: %v\n", err, backoff)
// }
type Notifer func(err error, backoff time.Duration)
// Option is a function type used to modify the Configuration of the retrier. Options allow
// for the flexible configuration of retry policies by applying user-defined settings.
//
// Parameters:
// - *Configuration: A pointer to the Configuration struct that allows modification of its fields.
//
// Returns:
// - Option: A functional option that modifies the Configuration struct, allowing customization of retry behavior.
type Option func(*Configuration)
// WithMaxRetries sets the maximum number of retries for the retry mechanism. When the specified
// number of retries is reached, the operation will stop, and the last error will be returned.
//
// Parameters:
// - retries: The maximum number of retry attempts.
//
// Returns:
// - Option: A functional option that modifies the Configuration to set the maxRetries field.
//
// Example:
//
// retrier.WithMaxRetries(5) sets the retry policy to attempt a maximum of 5 retries.
func WithMaxRetries(retries int) Option {
return func(c *Configuration) {
c.maxRetries = retries
}
}
// WithMaxDelay sets the maximum allowable delay between retry attempts. This option ensures that
// the delay between retries never exceeds the specified maximum, even with exponential backoff.
//
// Parameters:
// - delay: The maximum delay duration between retries.
//
// Returns:
// - Option: A functional option that modifies the Configuration to set the maxDelay field.
//
// Example:
//
// retrier.WithMaxDelay(2 * time.Second) ensures that delays between retries do not exceed 2 seconds.
func WithMaxDelay(delay time.Duration) Option {
return func(c *Configuration) {
c.maxDelay = delay
}
}
// WithMinDelay sets the minimum delay between retry attempts. This is the base duration from which
// the delay calculations start, and it ensures that retries do not occur too quickly in rapid succession.
//
// Parameters:
// - delay: The minimum delay duration between retries.
//
// Returns:
// - Option: A functional option that modifies the Configuration to set the minDelay field.
//
// Example:
//
// retrier.WithMinDelay(100 * time.Millisecond) ensures that retries wait at least 100ms before retrying.
func WithMinDelay(delay time.Duration) Option {
return func(c *Configuration) {
c.minDelay = delay
}
}
// WithBackoff sets the backoff strategy used to calculate the delay between retry attempts. The backoff
// strategy determines how the delay grows between retries, and can be customized to use strategies such as
// exponential backoff with jitter.
//
// Parameters:
// - strategy: A backoff function that defines the backoff strategy.
//
// Returns:
// - Option: A functional option that modifies the Configuration to set the backoff strategy.
//
// Example:
//
// retrier.WithBackoff(backoff.ExponentialWithFullJitter()) configures the retrier to use exponential backoff with full jitter.
func WithBackoff(strategy backoff.Backoff) Option {
return func(c *Configuration) {
c.backoff = strategy
}
}
// WithNotifier sets a notifier callback function that gets called on each retry attempt. This function
// allows users to log, monitor, or perform any action upon each retry attempt by providing error details
// and the duration of the backoff period.
//
// Parameters:
// - notifier: A function of type Notifer that will be called on each retry with the error and backoff duration.
//
// Returns:
// - Option: A functional option that modifies the Configuration to set the notifier function.
//
// Example:
//
// retrier.WithNotifier(logNotifier) sets up a notifier that logs each retry attempt.
func WithNotifier(notifier Notifer) Option {
return func(c *Configuration) {
c.notifier = notifier
}
}