xhttp

package
v0.0.81 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package xhttp eXtends Go's http. It provides things like an implementation of http.Client that does automatic retries.

Index

Constants

View Source
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

func NewJSONRequest(ctx context.Context, method, url string, data any) (*http.Request, error)

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.

func ParseRetryAfter added in v0.0.24

func ParseRetryAfter(value string) (time.Duration, time.Time, error)

ParseRetryAfter parses the Retry-After header in the response.

Types

type Client

type Client interface {
	Do(req *http.Request) (*http.Response, error)
}

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

func Do[T any](c Client, req *http.Request) (*Response[T], error)

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.

func Get added in v0.0.43

func Get[T any](ctx context.Context, c Client, url string) (*Response[T], error)

Get is a helper that creates a HTTP request with a GET method and no request body and calls Do. It will behave exactly as documented on Do.

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.

func (ResponseParseErr) Error added in v0.0.44

func (r ResponseParseErr) Error() string

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

type RetrierOnRetryFunc func(req *http.Request, res *http.Response, err error)

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL