fix(retry): handle Retry-After date and align review nits
This commit is contained in:
parent
e171d77353
commit
07e3f16ca8
3 changed files with 17 additions and 14 deletions
|
|
@ -139,8 +139,10 @@ func TestClassifyError_TimeoutPatterns(t *testing.T) {
|
||||||
"connection timed out",
|
"connection timed out",
|
||||||
"deadline exceeded",
|
"deadline exceeded",
|
||||||
"context deadline exceeded",
|
"context deadline exceeded",
|
||||||
|
"connection reset",
|
||||||
"connection reset by peer",
|
"connection reset by peer",
|
||||||
"tls handshake timeout",
|
"tls handshake timeout",
|
||||||
|
"EOF",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, msg := range patterns {
|
for _, msg := range patterns {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ type RetryPolicy struct {
|
||||||
Jitter RetryJitterFunc
|
Jitter RetryJitterFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
var retryAfterPattern = regexp.MustCompile(`(?i)retry[- ]after[:=]?\s*([^\s\r\n]+)`)
|
var retryAfterPattern = regexp.MustCompile(`(?i)retry[- ]after[:=]?\s*([^\r\n]+)`)
|
||||||
|
|
||||||
// DefaultLLMRetryPolicy returns the default retry behavior for LLM calls.
|
// DefaultLLMRetryPolicy returns the default retry behavior for LLM calls.
|
||||||
func DefaultLLMRetryPolicy() RetryPolicy {
|
func DefaultLLMRetryPolicy() RetryPolicy {
|
||||||
|
|
@ -101,7 +101,7 @@ func DoWithRetry[T any](ctx context.Context, policy RetryPolicy, fn func(context
|
||||||
|
|
||||||
sleepFn := policy.Sleep
|
sleepFn := policy.Sleep
|
||||||
if sleepFn == nil {
|
if sleepFn == nil {
|
||||||
sleepFn = sleepWithContext
|
sleepFn = sleepWithCtx
|
||||||
}
|
}
|
||||||
jitterFn := policy.Jitter
|
jitterFn := policy.Jitter
|
||||||
if jitterFn == nil {
|
if jitterFn == nil {
|
||||||
|
|
@ -232,18 +232,6 @@ func boundedAttemptTimeout(ctx context.Context, configured time.Duration) (time.
|
||||||
return configured, true
|
return configured, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func sleepWithContext(ctx context.Context, d time.Duration) error {
|
|
||||||
timer := time.NewTimer(d)
|
|
||||||
defer timer.Stop()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
case <-timer.C:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultJitter(max time.Duration) time.Duration {
|
func defaultJitter(max time.Duration) time.Duration {
|
||||||
if max <= 0 {
|
if max <= 0 {
|
||||||
return 0
|
return 0
|
||||||
|
|
|
||||||
|
|
@ -150,3 +150,16 @@ func TestLLMRetry_DoWithRetry_UsesRetryAfterFor429(t *testing.T) {
|
||||||
t.Fatalf("slept = %v, want 3s", slept)
|
t.Fatalf("slept = %v, want 3s", slept)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLLMRetry_ExtractRetryAfter_HTTPDate(t *testing.T) {
|
||||||
|
now := time.Date(2015, 10, 21, 7, 27, 0, 0, time.UTC)
|
||||||
|
err := errors.New("API request failed:\n Status: 429\n Retry-After: Wed, 21 Oct 2015 07:28:00 GMT")
|
||||||
|
|
||||||
|
delay, ok := extractRetryAfter(err, now)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected retry-after date to parse")
|
||||||
|
}
|
||||||
|
if delay != time.Minute {
|
||||||
|
t.Fatalf("delay = %v, want 1m", delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue