Skip to content

Commit 8460636

Browse files
authored
Merge pull request #475 from sarumont/ratex_nomenclature
refactor!: clarify variable naming for attempts in retryable operations
1 parent df29af8 commit 8460636

File tree

3 files changed

+47
-46
lines changed

3 files changed

+47
-46
lines changed

ratex/ratelimit.go

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@ import (
1818
type RateLimitParams struct {
1919
RateLimiter *rate.Limiter // can be nil to create a new rate limiter
2020

21-
// RetryAttempt represents the current retry attempt, starting at 1. This will increment for each retry
22-
RetryAttempt int
23-
MinDuration time.Duration
24-
MaxDuration time.Duration
21+
// Attempt represents the current attempt, starting at 1. This will increment for each (re)try
22+
Attempt int
23+
24+
MinDuration time.Duration
25+
MaxDuration time.Duration
2526
}
2627

2728
func RateLimit(ctx context.Context, params RateLimitParams) (*rate.Limiter, error) {
2829
ctx, span := telemetry.StartSpan(ctx, "rate-limiter-wait",
2930
trace.WithAttributes(
30-
attribute.Int("retry_attempt", params.RetryAttempt),
31+
attribute.Int("attempt", params.Attempt),
3132
attribute.Int64("min_duration_ms", params.MinDuration.Milliseconds()),
3233
attribute.Int64("max_duration_ms", params.MaxDuration.Milliseconds()),
3334
))
@@ -52,7 +53,7 @@ func RateLimit(ctx context.Context, params RateLimitParams) (*rate.Limiter, erro
5253

5354
// generateRateLimiter initializes a new rate limiter or sets a new limit on it.
5455
func generateRateLimiter(ctx context.Context, params RateLimitParams) (*rate.Limiter, error) {
55-
rateLimitDuration, err := generateRateLimitDuration(params.RetryAttempt, params.MinDuration, params.MaxDuration)
56+
rateLimitDuration, err := generateRateLimitDuration(params.Attempt, params.MinDuration, params.MaxDuration)
5657
if err != nil {
5758
return nil, fmt.Errorf("generating rate limit duration: %w", err)
5859
}
@@ -103,7 +104,7 @@ func generateRateLimitDuration(multiplier int, minDuration, maxDuration time.Dur
103104

104105
type RetryParams struct {
105106
ShouldRetry func(err error) bool
106-
MaxRetries int
107+
MaxAttempts int
107108
MinDuration time.Duration
108109
MaxDuration time.Duration
109110
}
@@ -116,8 +117,8 @@ func ExecRetryable[R any](ctx context.Context, closure func(ctx context.Context)
116117
)
117118

118119
// Validate params
119-
if params.MaxRetries <= 0 {
120-
params.MaxRetries = 1 // Default to at least one try
120+
if params.MaxAttempts <= 0 {
121+
params.MaxAttempts = 1 // Default to at least one try
121122
}
122123
if params.MinDuration <= 0 {
123124
params.MinDuration = 100 * time.Millisecond // Default min backoff
@@ -126,20 +127,20 @@ func ExecRetryable[R any](ctx context.Context, closure func(ctx context.Context)
126127
params.MaxDuration = params.MinDuration * 10 // Default max to 10x min
127128
}
128129

129-
retryFunc := func(ctx context.Context, retryAttempt int) (R, error) {
130+
tryFunc := func(ctx context.Context, attemptNum int) (R, error) {
130131
tryCtx, span := telemetry.StartSpan(ctx, "try",
131132
trace.WithAttributes(
132-
attribute.Int("retry_attempt", retryAttempt),
133-
attribute.Int("max_tries", params.MaxRetries),
133+
attribute.Int("attempt", attemptNum),
134+
attribute.Int("max_attempts", params.MaxAttempts),
134135
),
135136
)
136137
defer span.End()
137138
return closure(tryCtx)
138139
}
139140

140-
for i := 0; i < params.MaxRetries; i++ {
141-
retryAttempt := i + 1
142-
retVal, err = retryFunc(ctx, retryAttempt)
141+
for i := range params.MaxAttempts {
142+
attempt := i + 1
143+
retVal, err = tryFunc(ctx, attempt)
143144

144145
// no error means success - break out
145146
if err == nil {
@@ -152,20 +153,20 @@ func ExecRetryable[R any](ctx context.Context, closure func(ctx context.Context)
152153
}
153154

154155
// record event if we'll be attempting retries
155-
err = fmt.Errorf("try %d of %d: %w", retryAttempt, params.MaxRetries, err)
156+
err = fmt.Errorf("try %d of %d: %w", attempt, params.MaxAttempts, err)
156157
telemetry.AddEvent(ctx, err.Error())
157158

158-
if retryAttempt != params.MaxRetries {
159+
if attempt != params.MaxAttempts {
159160
// If error and we haven't hit max tries,
160161
// generate rate limiter to delay retries.
161162
// This will jitter a wait time before the next iteration.
162163
//
163164
// We abort on rate limit errors (e.g., ctx cancel) instead of continuing
164165
rlParams := RateLimitParams{
165-
RateLimiter: rateLimiter,
166-
RetryAttempt: retryAttempt,
167-
MinDuration: params.MinDuration,
168-
MaxDuration: params.MaxDuration,
166+
RateLimiter: rateLimiter,
167+
Attempt: attempt,
168+
MinDuration: params.MinDuration,
169+
MaxDuration: params.MaxDuration,
169170
}
170171
rateLimiter, err = RateLimit(ctx, rlParams)
171172
if err != nil {
@@ -176,7 +177,7 @@ func ExecRetryable[R any](ctx context.Context, closure func(ctx context.Context)
176177
}
177178

178179
if err != nil {
179-
return retVal, fmt.Errorf("hit max tries %d: %w", params.MaxRetries, err)
180+
return retVal, fmt.Errorf("hit max tries %d: %w", params.MaxAttempts, err)
180181
}
181182
return retVal, nil
182183
}

ratex/ratelimit_test.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestExecRetryable(t *testing.T) {
2020
}
2121
params := RetryParams{
2222
ShouldRetry: func(err error) bool { return true },
23-
MaxRetries: 3,
23+
MaxAttempts: 3,
2424
MinDuration: 10 * time.Millisecond,
2525
MaxDuration: 50 * time.Millisecond,
2626
}
@@ -40,7 +40,7 @@ func TestExecRetryable(t *testing.T) {
4040
}
4141
params := RetryParams{
4242
ShouldRetry: func(err error) bool { return true },
43-
MaxRetries: 3,
43+
MaxAttempts: 3,
4444
MinDuration: 10 * time.Millisecond,
4545
MaxDuration: 50 * time.Millisecond,
4646
}
@@ -63,7 +63,7 @@ func TestExecRetryable(t *testing.T) {
6363
}
6464
params := RetryParams{
6565
ShouldRetry: func(err error) bool { return false },
66-
MaxRetries: 3,
66+
MaxAttempts: 3,
6767
MinDuration: 10 * time.Millisecond,
6868
MaxDuration: 50 * time.Millisecond,
6969
}
@@ -73,15 +73,15 @@ func TestExecRetryable(t *testing.T) {
7373
require.Equal(t, "non-retryable error", err.Error())
7474
})
7575

76-
t.Run("Retryable failures exceeding MaxRetries", func(t *testing.T) {
76+
t.Run("Retryable failures exceeding MaxAttempts", func(t *testing.T) {
7777
attempts := 0
7878
closure := func(ctx context.Context) (string, error) {
7979
attempts++
8080
return "", errors.New("retryable error")
8181
}
8282
params := RetryParams{
8383
ShouldRetry: func(err error) bool { return true },
84-
MaxRetries: 3,
84+
MaxAttempts: 3,
8585
MinDuration: 10 * time.Millisecond,
8686
MaxDuration: 50 * time.Millisecond,
8787
}
@@ -106,7 +106,7 @@ func TestExecRetryable(t *testing.T) {
106106
}
107107
params := RetryParams{
108108
ShouldRetry: func(err error) bool { return true },
109-
MaxRetries: 3,
109+
MaxAttempts: 3,
110110
MinDuration: 10 * time.Millisecond,
111111
MaxDuration: 50 * time.Millisecond,
112112
}
@@ -124,7 +124,7 @@ func TestExecRetryable(t *testing.T) {
124124
}
125125
params := RetryParams{
126126
ShouldRetry: func(err error) bool { return true },
127-
MaxRetries: 3,
127+
MaxAttempts: 3,
128128
MinDuration: 100 * time.Millisecond,
129129
MaxDuration: 200 * time.Millisecond,
130130
}
@@ -143,7 +143,7 @@ func TestExecRetryable(t *testing.T) {
143143
}
144144
params := RetryParams{
145145
ShouldRetry: func(err error) bool { return true },
146-
MaxRetries: 0, // Should default to 1
146+
MaxAttempts: 0, // Should default to 1
147147
MinDuration: 0, // Should default to 100ms
148148
MaxDuration: 0, // Should default to 100ms * 10 = 1s
149149
}
@@ -159,7 +159,7 @@ func TestExecRetryable(t *testing.T) {
159159
}
160160
params := RetryParams{
161161
ShouldRetry: func(err error) bool { return true },
162-
MaxRetries: 3,
162+
MaxAttempts: 3,
163163
MinDuration: 100 * time.Millisecond,
164164
MaxDuration: 50 * time.Millisecond, // Will be set to 100ms * 10 = 1s
165165
}
@@ -174,7 +174,7 @@ func TestExecRetryable(t *testing.T) {
174174
}
175175
params := RetryParams{
176176
ShouldRetry: func(err error) bool { return true },
177-
MaxRetries: 3,
177+
MaxAttempts: 3,
178178
MinDuration: 10 * time.Millisecond,
179179
MaxDuration: 50 * time.Millisecond,
180180
}
@@ -234,10 +234,10 @@ func TestRateLimit(t *testing.T) {
234234

235235
t.Run("New limiter", func(t *testing.T) {
236236
params := RateLimitParams{
237-
RateLimiter: nil,
238-
RetryAttempt: 1,
239-
MinDuration: 10 * time.Millisecond,
240-
MaxDuration: 20 * time.Millisecond,
237+
RateLimiter: nil,
238+
Attempt: 1,
239+
MinDuration: 10 * time.Millisecond,
240+
MaxDuration: 20 * time.Millisecond,
241241
}
242242
limiter, err := RateLimit(ctx, params)
243243
require.NoError(t, err)
@@ -247,10 +247,10 @@ func TestRateLimit(t *testing.T) {
247247
t.Run("Existing limiter update", func(t *testing.T) {
248248
existing := rate.NewLimiter(rate.Every(100*time.Millisecond), 1)
249249
params := RateLimitParams{
250-
RateLimiter: existing,
251-
RetryAttempt: 2,
252-
MinDuration: 10 * time.Millisecond,
253-
MaxDuration: 20 * time.Millisecond,
250+
RateLimiter: existing,
251+
Attempt: 2,
252+
MinDuration: 10 * time.Millisecond,
253+
MaxDuration: 20 * time.Millisecond,
254254
}
255255
limiter, err := RateLimit(ctx, params)
256256
require.NoError(t, err)
@@ -260,10 +260,10 @@ func TestRateLimit(t *testing.T) {
260260
t.Run("Context cancel during wait", func(t *testing.T) {
261261
ctx, cancel := context.WithCancel(context.Background())
262262
params := RateLimitParams{
263-
RateLimiter: nil,
264-
RetryAttempt: 1,
265-
MinDuration: 100 * time.Millisecond,
266-
MaxDuration: 200 * time.Millisecond,
263+
RateLimiter: nil,
264+
Attempt: 1,
265+
MinDuration: 100 * time.Millisecond,
266+
MaxDuration: 200 * time.Millisecond,
267267
}
268268
go func() {
269269
time.Sleep(50 * time.Millisecond)

sql/sql_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ func TestDBRetryableOperations(t *testing.T) {
380380

381381
retryParams := ratex.RetryParams{
382382
ShouldRetry: func(err error) bool { return true },
383-
MaxRetries: 3,
383+
MaxAttempts: 3,
384384
MinDuration: 10 * time.Millisecond,
385385
MaxDuration: 50 * time.Millisecond,
386386
}
@@ -412,7 +412,7 @@ func TestDBRetryableOperations(t *testing.T) {
412412
require.Error(t, err)
413413
})
414414

415-
t.Run("ExecContextRetryable - Retryable failures exceeding MaxRetries", func(t *testing.T) {
415+
t.Run("ExecContextRetryable - Retryable failures exceeding MaxAttempts", func(t *testing.T) {
416416
closure := func(ctx context.Context) (gosql.Result, error) {
417417
return nil, errors.New("retryable error")
418418
}

0 commit comments

Comments
 (0)