Documentation
¶
Overview ¶
Package xhttp eXtends Go's http. It provides things like an implementation of http.Client that does automatic retries.
Index ¶
- Constants
- func NewJSONRequest(ctx context.Context, method, url string, data any) (*http.Request, error)
- func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*http.Request, error)
- func ParseRetryAfter(value string) (time.Duration, time.Time, error)
- type Client
- type Response
- type ResponseParseErr
- type RetrierOnRequestDoneFunc
- type RetrierOnRetryFunc
- type RetrierOption
- func RetrierWithJitter(jitter time.Duration) RetrierOption
- func RetrierWithMaxSleepPeriod(maxPeriod time.Duration) RetrierOption
- func RetrierWithMinSleepPeriod(minPeriod time.Duration) RetrierOption
- func RetrierWithOnRequestDone(f RetrierOnRequestDoneFunc) RetrierOption
- func RetrierWithOnRetry(f RetrierOnRetryFunc) RetrierOption
- func RetrierWithRequestTimeout(timeout time.Duration) RetrierOption
- func RetrierWithRespCheck() RetrierOption
- func RetrierWithSleep(sleep func(context.Context, time.Duration)) RetrierOption
- func RetrierWithStatuses(statuses ...int) RetrierOption
Constants ¶
const ( // DefaultMinSleepPeriod is the default min sleep period between retries (which is increased exponentially). DefaultMinSleepPeriod = 250 * time.Millisecond // DefaultMaxSleepPeriod is the default max sleep period between retries. DefaultMaxSleepPeriod = 30 * time.Second )
Variables ¶
This section is empty.
Functions ¶
func NewJSONRequest ¶ added in v0.0.42
NewJSONRequest is a wrapper that will marshall the given data as a JSON and call NewRequestWithContext. It makes it practical to create HTTP requests that send JSON bodies with detailed user agents (what we want most of the time).
func NewRequestWithContext ¶ added in v0.0.36
func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*http.Request, error)
NewRequestWithContext is a wrapper that will call http.NewRequestWithContext and add an User-Agent header according to RFC 7231. It is a more complete User-Agent than Go's default, including proper Go version and the name of the main package of the binary with its version. The user agent will be on the format: Go/<go version> <main package name>/<main version> This is intended for internal communication between services since the user agent contains a lot of details about the client. If this seems like too much information to send to a public service just use http.NewRequestWithContext.
Types ¶
type Client ¶
Client abstracts a http.Client, allowing us to create wrappers for http clients adding useful functionality like retry and metrics. It has the same API as http.Client and is intended to be a drop-in replacement (but not all methods are supported yet). The client will have to read the entire request body in memory in order to properly retry a failed request.
func NewRetrierClient ¶
func NewRetrierClient(c Client, options ...RetrierOption) Client
NewRetrierClient wraps the given client with retry logic. The returned Client will automatically retry failed requests.
type Response ¶ added in v0.0.42
type Response[T any] struct { *http.Response // RawBody is the raw response from where Value was parsed (useful mostly for debugging). RawBody []byte // Value is the parsed JSON response. Value T // Elapsed is how long it took for the request to be answered. Elapsed time.Duration }
Response is an extension of http.Response that contains parsed data instead of a response body.
func Do ¶ added in v0.0.42
Do calls Client.Do and unmarshalls the HTTP response as a JSON of type [T]. The returned Response embeds the original http.Response with the addition of the [Response.Obj] field that holds the parsed response.
The original http.Response.Body will always be read and closed, the caller should ignore this field and use Response.Value to access the parsed response or use errors.As to check details in the case of an error (eg. debugging malformed JSON).
If the response is not valid JSON an error of type ResponseParseErr is returned.
type ResponseParseErr ¶ added in v0.0.44
type ResponseParseErr struct {
Err error
Body []byte
StatusCode int
// Elapsed is how long it took for the request to be answered.
Elapsed time.Duration
}
ResponseParseErr is the error returned by Do if parsing the response body fails.
type RetrierOnRequestDoneFunc ¶ added in v0.0.22
type RetrierOnRequestDoneFunc func(req *http.Request, res *http.Response, err error, elapsed time.Duration)
RetrierOnRequestDoneFunc is the callback called when using RetrierWithOnRequestDone. The *http.Request is the original http request that just finished. The *http.Response is the response returned by the Client.Do call. The [error] is the response error returned by the Client.Do call. The time.Duration is how long the http request took to be finished. This is called for every request that is done, including retries.
type RetrierOnRetryFunc ¶ added in v0.0.22
RetrierOnRetryFunc is the callback called when using RetrierWithOnRetry. The *http.Request is the original http request that just finished. The *http.Response is the response returned by the Client.Do call. The [error] is the response error returned by the Client.Do call. This is called every time a request is retried (it failed and retrier decided to retry it). The callback can read the http.Response body if it wants, for debugging for example, but it doesn't have to close the body, the retries always close the response bodies when retrying.
type RetrierOption ¶
type RetrierOption func(*retrierClient)
RetrierOption is used to configure retrier clients created with NewRetrierClient.
func RetrierWithJitter ¶ added in v0.0.59
func RetrierWithJitter(jitter time.Duration) RetrierOption
RetrierWithJitter configures the maximum jitter between retries. When calculating the retry period based on min/max/exponential increase a random jitter will be added on top of the retry period using this jitter duration as the random max. This is useful to avoid bursts of retries, which even as they increase exponentially will be made on a very similar cadence if the initial request happens at the same time.
func RetrierWithMaxSleepPeriod ¶ added in v0.0.17
func RetrierWithMaxSleepPeriod(maxPeriod time.Duration) RetrierOption
RetrierWithMaxSleepPeriod configures the max period that the retrier will sleep between retries. If not defined it will default DefaultMaxSleepPeriod.
func RetrierWithMinSleepPeriod ¶
func RetrierWithMinSleepPeriod(minPeriod time.Duration) RetrierOption
RetrierWithMinSleepPeriod configures the min period that the retrier will sleep between retries. The retrier uses an exponential backoff, so this will be only the initial sleep period, that then grows exponentially. If not defined it will default DefaultMinSleepPeriod.
func RetrierWithOnRequestDone ¶ added in v0.0.22
func RetrierWithOnRequestDone(f RetrierOnRequestDoneFunc) RetrierOption
RetrierWithOnRequestDone configures a callback function that will be called for each request done by the retrier. This includes retried requests. The callback is called after a response/error is received but before the response/error is processed (for retrying). The callback is called from the same goroutine that called the retrier Do method.
func RetrierWithOnRetry ¶ added in v0.0.22
func RetrierWithOnRetry(f RetrierOnRetryFunc) RetrierOption
RetrierWithOnRetry configures a callback function that will be called for each request retry. It includes only retried requests. The callback is called after a response/error is received and it is decided that the request is a retry-able failure but before the request is actually retried. The callback is called from the same goroutine that called the retrier Do method.
func RetrierWithRequestTimeout ¶
func RetrierWithRequestTimeout(timeout time.Duration) RetrierOption
RetrierWithRequestTimeout configures a client retrier with the given timeout. This timeout is used per request/try. When calling Client.Do if the request has a context with a deadline longer than this timeout the retrier will keep retrying until the parent request context is cancelled/deadline expires. If this timeout is bigger than the deadline of the request context then the request context will be respected A context is created with this timeout and the original request context as parent for each request.
This is useful for situations where the service where the request is sent is hanging forever but only on some requests. On such a situation you can have two timeouts. One provided on the request passed to Client.Do on the request context and the timeout defined with this option. Lets say the overall timeout is 10 min (when you created the original request) and this configuration here is 30 secs. Now every 30 sec the request will fail since it timeouted and will be retried, until the parent timeout of 10 min expires.
func RetrierWithRespCheck ¶ added in v0.0.17
func RetrierWithRespCheck() RetrierOption
RetrierWithRespCheck configures the retrier to read the responses of successful HTTP requests and retry if reading the response fails (like the connection dropping during the response transmission). Beware that this option involves reading the entire response body in memory, it is not a good idea to use this with streams.
func RetrierWithSleep ¶
func RetrierWithSleep(sleep func(context.Context, time.Duration)) RetrierOption
RetrierWithSleep configures the sleep function used to sleep between retries, usually used for testing.
func RetrierWithStatuses ¶
func RetrierWithStatuses(statuses ...int) RetrierOption
RetrierWithStatuses will configure the retrier to retry when these specific status code are received. This option only adds more status codes that will be retried, it will still retry on default error status codes like http.StatusServiceUnavailable and http.StatusInternalServerError