You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement Retry middleware to support retry mechanisms for HTTP requests, offering various backoff strategies and configurations.
Implement Cache middleware for in-memory caching of HTTP responses, allowing custom cache key strategies and TTL-based eviction.
Also, add test coverage for both middlewares to ensure correct behavior under different conditions. Update README to document new middlewares with examples and configuration options.
-`Repeater` - sets repeater to retry failed requests. Doesn't provide repeater implementation but wraps it. Compatible with any repeater (for example [go-pkgz/repeater](https://github.com/go-pkgz/repeater)) implementing a single method interface `Do(ctx context.Context, fun func() error, errors ...error) (err error)` interface.
39
42
-`Cache` - sets any `LoadingCache` implementation to be used for request/response caching. Doesn't provide cache, but wraps it. Compatible with any cache (for example a family of caches from [go-pkgz/lcw](https://github.com/go-pkgz/lcw)) implementing a single-method interface `Get(key string, fn func() (interface{}, error)) (val interface{}, err error)`
40
43
-`Logger` - sets logger, compatible with any implementation of a single-method interface `Logf(format string, args ...interface{})`, for example [go-pkgz/lgr](https://github.com/go-pkgz/lgr)
`MaxConcurrent` middleware can be used to limit the concurrency of a given requester and limit overall concurrency for multiple requesters. For the first case, `MaxConcurrent(N)` should be created in the requester chain of middlewares. For example, `rq := requester.New(http.Client{Timeout: 3 * time.Second}, middleware.MaxConcurrent(8))`. To make it global, `MaxConcurrent` should be created once, outside the chain, and passed into each requester. For example:
middleware.RetryOnCodes(503, 502), // retry only on specific codes
81
+
// or middleware.RetryExcludeCodes(404, 401), // alternatively, retry on all except these codes
82
+
))
83
+
```
84
+
85
+
Default configuration:
86
+
- 3 attempts
87
+
- Initial delay: 100ms
88
+
- Max delay: 30s
89
+
- Exponential backoff
90
+
- 10% jitter
91
+
- Retries on 5xx status codes
92
+
93
+
Retry Options:
94
+
-`RetryWithBackoff(t BackoffType)` - set backoff strategy (Constant, Linear, or Exponential)
95
+
-`RetryMaxDelay(d time.Duration)` - cap the maximum delay between retries
96
+
-`RetryWithJitter(f float64)` - add randomization to delays (0-1.0 factor)
97
+
-`RetryOnCodes(codes ...int)` - retry only on specific status codes
98
+
-`RetryExcludeCodes(codes ...int)` - retry on all codes except specified
99
+
100
+
Note: `RetryOnCodes` and `RetryExcludeCodes` are mutually exclusive and can't be used together.
101
+
102
+
### Cache middleware
103
+
104
+
Cache middleware provides an **in-memory caching layer** for HTTP responses. It improves performance by avoiding repeated network calls for the same request.
Logger should implement `Logger` interface with a single method `Logf(format string, args ...interface{})`.
51
178
For convenience, func type `LoggerFunc` is provided as an adapter to allow the use of ordinary functions as `Logger`.
@@ -63,19 +190,11 @@ logging options:
63
190
64
191
Note: If logging is allowed, it will log the URL, method, and may log headers and the request body. It may affect application security. For example, if a request passes some sensitive information as part of the body or header. In this case, consider turning logging off or providing your own logger to suppress all that you need to hide.
65
192
66
-
### MaxConcurrent
67
-
68
-
MaxConcurrent middleware can be used to limit the concurrency of a given requester and limit overall concurrency for multiple requesters. For the first case, `MaxConcurrent(N)` should be created in the requester chain of middlewares. For example, `rq := requester.New(http.Client{Timeout: 3 * time.Second}, middleware.MaxConcurrent(8))`. To make it global, `MaxConcurrent` should be created once, outside the chain, and passed into each requester. For example:
If the request is limited, it will wait till the limit is released.
77
195
78
-
### Cache
196
+
### Cache middleware interface
197
+
79
198
Cache expects the `LoadingCache` interface to implement a single method: `Get(key string, fn func() (interface{}, error)) (val interface{}, err error)`. [LCW](https://github.com/go-pkgz/lcw/) can be used directly, and in order to adopt other caches, see the provided `LoadingCacheFunc`.
80
199
81
200
#### Caching Key and Allowed Requests
@@ -92,12 +211,11 @@ Several options define what part of the request will be used for the key:
`Cache` is **not compatible** with HTTP streaming mode. Practically, this is rare and exotic, but allowing `Cache` will effectively transform the streaming response into a "get it all" typical response. This is due to the fact that the cache has to read the response body fully to save it, so technically streaming will be working, but the client will receive all the data at once.
99
217
100
-
### Repeater
218
+
### Repeater middleware interface
101
219
102
220
`Repeater` expects a single method interface `Do(fn func() error, failOnCodes ...error) (err error)`. [repeater](github.com/go-pkgz/repeater) can be used directly.
0 commit comments