feat(retry): Add retry logic with exponential backoff for HTTP requests#20
feat(retry): Add retry logic with exponential backoff for HTTP requests#20
Conversation
- Add RetryConfig type with configurable retry parameters - Update ClientOptions to include RetryConfig field - Implement retry helper functions for error detection and backoff calculation - Add executeWithRetry method with exponential backoff logic - Integrate retry logic into all HTTP methods (ListModels, ListProviderModels, ListTools, GenerateContent, GenerateContentStream, HealthCheck) - Add comprehensive tests covering various retry scenarios - Default retry configuration: enabled with 3 max attempts, 2s initial backoff, 30s max backoff, 2x multiplier - Retry on status codes: 408, 429, 500, 502, 503, 504 - Retry on network errors: timeouts, connection failures, DNS errors - Respect context cancellation during retries Co-authored-by: Eden Reich <edenreich@users.noreply.github.com>
Signed-off-by: Eden Reich <eden.reich@gmail.com>
|
🎉 This PR is included in version 1.12.0-rc.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
@claude Please analyse the changes and tell me if as a consumer of this library can I configure the status codes that are retryable ? Also I would like to know if there is a callback that I can use to log out the retries in the consumer application for better visibility. |
|
Claude finished @edenreich's task —— View job Analysis of Retry ImplementationI've analyzed the retry implementation changes in this PR. Here are the answers to your questions: ❌ Status Code ConfigurabilityNo, you cannot configure which status codes are retryable as a consumer of this library. The retryable status codes are hardcoded in the func isRetryableStatusCode(statusCode int) bool {
switch statusCode {
case
http.StatusRequestTimeout, // 408
http.StatusTooManyRequests, // 429
http.StatusInternalServerError, // 500
http.StatusBadGateway, // 502
http.StatusServiceUnavailable, // 503
http.StatusGatewayTimeout: // 504
return true
default:
return false
}
}These status codes are fixed and cannot be modified through the ❌ Retry Logging/Callback MechanismNo, there is no callback or logging mechanism available for consumers to monitor retry attempts. The current implementation:
🔧 Current RetryConfig OptionsThe type RetryConfig struct {
Enabled bool // Enable/disable retry logic
MaxAttempts int // Max retry attempts (including initial)
InitialBackoffSec int // Initial backoff delay in seconds
MaxBackoffSec int // Maximum backoff delay in seconds
BackoffMultiplier int // Multiplier for exponential backoff
}💡 Suggestions for EnhancementTo address your needs, the retry implementation could be enhanced with:
These enhancements would provide the configurability and observability you're looking for without breaking existing functionality. Todo List:
|
|
@claude Sounds like a plan, let's implement these. |
|
Claude finished @edenreich's task —— View job Implementation Complete! 🎉I've successfully implemented both requested enhancements to the retry logic: Todo List
✅ Configurable Status CodesAdded
✅ Retry Callback MechanismAdded
Usage ExamplesConfigure custom retryable status codes: retryConfig := &RetryConfig{
Enabled: true,
MaxAttempts: 3,
RetryableStatusCodes: []int{418, 422, 503}, // Only retry these
}Add retry logging/monitoring: retryConfig := &RetryConfig{
Enabled: true,
MaxAttempts: 3,
OnRetry: func(attempt int, err error, delay time.Duration) {
log.Printf("Retry attempt %d: %v (waiting %v)", attempt, err, delay)
},
}Combine both features: retryConfig := &RetryConfig{
Enabled: true,
MaxAttempts: 3,
RetryableStatusCodes: []int{418, 503, 504},
OnRetry: func(attempt int, err error, delay time.Duration) {
metrics.IncrementRetryCounter()
log.Printf("Retrying request (attempt %d): %v", attempt, err)
},
}✅ Backward Compatibility
✅ Comprehensive TestingAdded 4 new test functions with 15+ test cases covering:
Results: All tests pass (21.045s) ✅ | Linter: 0 issues ✅ Changes Committed
Commit: |
- Add RetryableStatusCodes field to RetryConfig for custom status codes - Add OnRetry callback for retry event logging and monitoring - Maintain backward compatibility with default behavior - Update isRetryableStatusCode to use configurable codes - Add comprehensive test coverage for new functionality Co-authored-by: Eden Reich <edenreich@users.noreply.github.com>
* refactor(tests): Remove unnecessary blank line in TestIsRetryableStatusCode Signed-off-by: Eden Reich <eden.reich@gmail.com> * chore(release): 🔖 1.12.0-rc.1 [skip ci] ## [1.12.0-rc.1](v1.11.1...v1.12.0-rc.1) (2025-08-22) ### ✨ Features * **retry:** Add configurable status codes and callback mechanism ([1d3cefa](1d3cefa)) * **retry:** Add retry logic with exponential backoff for HTTP requests ([0d1a57a](0d1a57a)) ### ♻️ Improvements * **retry:** Clean up comments ([b5a32db](b5a32db)) * **tests:** Remove unnecessary blank line in TestIsRetryableStatusCode ([223ab26](223ab26)) ### 🔧 Miscellaneous * Remove redundant comments ([fbbe49f](fbbe49f)) --------- Signed-off-by: Eden Reich <eden.reich@gmail.com>
|
🎉 This PR is included in version 1.12.0-rc.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
…unction Signed-off-by: Eden Reich <eden.reich@gmail.com>
|
🎉 This PR is included in version 1.12.0-rc.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
* fix(headers): Remove redundant comment in TestWithHeaders Signed-off-by: Eden Reich <eden.reich@gmail.com> * refactor(retry): Remove comments from retryable status code tests for clarity Signed-off-by: Eden Reich <eden.reich@gmail.com> * chore(release): 🔖 1.12.0-rc.1 [skip ci] ## [1.12.0-rc.1](v1.11.1...v1.12.0-rc.1) (2025-08-22) ### ✨ Features * **retry:** Add configurable status codes and callback mechanism ([1d3cefa](1d3cefa)) * **retry:** Add retry logic with exponential backoff for HTTP requests ([0d1a57a](0d1a57a)) ### ♻️ Improvements * **retry:** Clean up comments ([b5a32db](b5a32db)) ### 🐛 Bug Fixes * **headers:** Remove redundant comment in TestWithHeaders ([a6a6cbb](a6a6cbb)) ### 🔧 Miscellaneous * Remove redundant comments ([fbbe49f](fbbe49f)) * Testing the release ([#22](#22)) ([05b9687](05b9687)) * chore(release): 🔖 1.12.0-rc.1 [skip ci] ## [1.12.0-rc.1](v1.11.1...v1.12.0-rc.1) (2025-08-22) ### ✨ Features * **retry:** Add configurable status codes and callback mechanism ([1d3cefa](1d3cefa)) * **retry:** Add retry logic with exponential backoff for HTTP requests ([0d1a57a](0d1a57a)) ### ♻️ Improvements * **retry:** Clean up comments ([b5a32db](b5a32db)) * **retry:** Remove comments from retryable status code tests for clarity ([5948350](5948350)) * **retry:** Remove redundant comments in isRetryableStatusCode function ([930dc15](930dc15)) ### 🐛 Bug Fixes * **headers:** Remove redundant comment in TestWithHeaders ([468f356](468f356)) ### 🔧 Miscellaneous * **release:** 🔖 1.12.0-rc.1 [skip ci] ([d36f1ab](d36f1ab)) * Remove redundant comments ([fbbe49f](fbbe49f)) * Testing the release ([#22](#22)) ([05b9687](05b9687)) * feat: Add Retry Mechanism section to README and implement parseRetryAfter function with tests also for rate-limiting retries Signed-off-by: Eden Reich <eden.reich@gmail.com> * chore(release): 🔖 1.12.0-rc.2 [skip ci] ## [1.12.0-rc.2](v1.12.0-rc.1...v1.12.0-rc.2) (2025-08-22) ### ✨ Features * Add Retry Mechanism section to README and implement parseRetryAfter function with tests also for rate-limiting retries ([ce74bad](ce74bad)) --------- Signed-off-by: Eden Reich <eden.reich@gmail.com>
|
🎉 This PR is included in version 1.12.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Implements retry logic with exponential backoff for HTTP requests as specified in issue #19.
Changes
RetryConfigtype with configurable parametersClientOptionsto include retry configurationCloses #19
Generated with Claude Code