Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Drain ¶
func Drain(size int64) frolic.TripperFunc
Drain attempts to enable HTTP connection reuse. It does so by wrapping the response body in its own type that implements io.ReadCloser. Calling Close on this type atomatically reads up to size into /dev/null.
If there is more data in the response body, then the connection won't be reused and we'll pay the penalty of setting up a new one.
This makes it safe to defer resp.Body.Close() as long as this tripperware is the first one in the frolic.Chain.
func SafeRetry ¶
SafeRetry determines if a request is safe to be retried.
This implementation is very simple:
- HTTP methods specified as idempotent can be retried.
- Any other method cannot be retried.
It's possible that PATCH, PUT or POST can be retried as well, because the server has some kind of way to deduplicate those requests. For example, the presence and use of an Idempotency-Key header, or some unique ID in the payload. For those cases, you should implement your own function.
func ShallowClone ¶
ShallowClone creates a shallow clone of an http.Request.
This means that the returned struct is new, but any fields within it like pointers to structs, arrays/slices, maps and interfaces still point to the originals. If you're going to modify any of those fields, you need to clone those fields as well.
http.Request.Headers has a Clone function, and you can use CloneURL to clone the http.Request.URL.
You can use http.Request.Clone to create a full clone, but that's rarely necessary.
func UserAgent ¶
func UserAgent(ua string) frolic.TripperFunc
UserAgent sets the specified user-agent on all requests.
It's recommended to use this format: <name>/<version> (+<URI>). The URI should be something you can be contacted at, such as the address of an issue tracker, or an e-mail address (mailto:).
Types ¶
type Retry ¶
type Retry struct {
CanRetry func(req *http.Request) bool
BufferSize int64
Logger *slog.Logger
Backoff []time.Duration
// contains filtered or unexported fields
}
Retry performs a simple retry-with-backoff for a request. It only retries a request when an HTTP 5xx is returned by the server. It's meant to smooth out small transient errors, it's not a rate-limiter or a circuit breaker.
Retry should be towards the end of a frolic.Tripperware chain.
Retry is automatically configured with:
- [Retry.CanRetry] set to SafeRetry.
- [Retry.BufferSize] set to 64 KiB.
- [Retry.Logger] set to a discard logger.
- [Retry.Backoff] with 3 attempts with 50ms increases.
Whether a request can be retried at all depends on two things:
- The return value of the [Retry.CanRetry] function.
- If http.Request.Body is not nil, then http.Request.GetBody must be not nil as well.
If those conditions are met then a request is retried if:
- The next transport does not return an error. If it does, we assume the error is not transient and don't attempt to retry the request.
- The server returned a 5xx without a Retry-After or X-RateLimit-Reset header also being present in the response.
func (*Retry) Trip ¶
func (r *Retry) Trip(next http.RoundTripper) http.RoundTripper