hedgedhttp

package module
v0.6.3 Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2021 License: MIT Imports: 7 Imported by: 30

README

hedgedhttp

build-img pkg-img reportcard-img coverage-img version-img

Hedged HTTP client which helps to reduce tail latency at scale.

Rationale

See paper Tail at Scale by Jeffrey Dean, Luiz André Barroso. In short: the client first sends one request, but then sends an additional request after a timeout if the previous hasn't returned an answer in the expected time. The client cancels remaining requests once the first result is received.

Acknowledge

Thanks to Bohdan Storozhuk for the review and powerful hints.

Features

  • Simple API.
  • Easy to integrate.
  • Optimized for speed.
  • Clean and tested code.
  • Supports http.Client and http.RoundTripper.
  • Dependency-free.

Install

Go version 1.16+

go get github.com/cristalhq/hedgedhttp

Example

ctx := context.Background()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://google.com", http.NoBody)
if err != nil {
	panic(err)
}

timeout := 10 * time.Millisecond
upto := 7
client := &http.Client{Timeout: time.Second}
hedged := hedgedhttp.NewClient(timeout, upto, client)

// will take `upto` requests, with a `timeout` delay between them
resp, err := hedged.Do(req)
if err != nil {
	panic(err)
}
defer resp.Body.Close()

// and do something with resp

Also see examples: examples_test.go.

Documentation

See these docs.

License

MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsHedgedRequest added in v0.6.2

func IsHedgedRequest(r *http.Request) bool

IsHedgedRequest reports when a request is hedged.

func NewClient

func NewClient(timeout time.Duration, upto int, client *http.Client) *http.Client

NewClient returns a new http.Client which implements hedged requests pattern. Given Client starts a new request after a timeout from previous request. Starts no more than upto requests.

func NewRoundTripper

func NewRoundTripper(timeout time.Duration, upto int, rt http.RoundTripper) http.RoundTripper

NewRoundTripper returns a new http.RoundTripper which implements hedged requests pattern. Given RoundTripper starts a new request after a timeout from previous request. Starts no more than upto requests.

Types

type ErrorFormatFunc added in v0.2.0

type ErrorFormatFunc func([]error) string

ErrorFormatFunc is called by MultiError to return the list of errors as a string.

type MultiError added in v0.2.0

type MultiError struct {
	Errors        []error
	ErrorFormatFn ErrorFormatFunc
}

MultiError is an error type to track multiple errors. This is used to accumulate errors in cases and return them as a single "error". Insiper by https://github.com/hashicorp/go-multierror

func (*MultiError) Error added in v0.2.0

func (e *MultiError) Error() string

func (*MultiError) ErrorOrNil added in v0.2.0

func (e *MultiError) ErrorOrNil() error

ErrorOrNil returns an error if there are some.

func (*MultiError) String added in v0.2.0

func (e *MultiError) String() string

type Stats added in v0.6.0

type Stats struct {
	// contains filtered or unexported fields
}

Stats object that can be queried to obtain certain metrics and get better observability.

func NewClientAndStats added in v0.6.0

func NewClientAndStats(timeout time.Duration, upto int, client *http.Client) (*http.Client, *Stats)

NewClientAndStats returns a new http.Client which implements hedged requests pattern And Stats object that can be queried to obtain client's metrics. Given Client starts a new request after a timeout from previous request. Starts no more than upto requests.

func NewRoundTripperAndStats added in v0.6.0

func NewRoundTripperAndStats(timeout time.Duration, upto int, rt http.RoundTripper) (http.RoundTripper, *Stats)

NewRoundTripperAndStats returns a new http.RoundTripper which implements hedged requests pattern And Stats object that can be queried to obtain client's metrics. Given RoundTripper starts a new request after a timeout from previous request. Starts no more than upto requests.

func (*Stats) ActualRoundTrips added in v0.6.0

func (s *Stats) ActualRoundTrips() uint64

ActualRoundTrips returns count of requests that were actually sent.

func (*Stats) CanceledByUserRoundTrips added in v0.6.0

func (s *Stats) CanceledByUserRoundTrips() uint64

CanceledByUserRoundTrips returns count of requests that were canceled by user, using request context.

func (*Stats) CanceledSubRequests added in v0.6.0

func (s *Stats) CanceledSubRequests() uint64

CanceledSubRequests returns count of hedged sub-requests that were canceled by transport.

func (*Stats) FailedRoundTrips added in v0.6.0

func (s *Stats) FailedRoundTrips() uint64

FailedRoundTrips returns count of requests that failed.

func (*Stats) RequestedRoundTrips added in v0.6.0

func (s *Stats) RequestedRoundTrips() uint64

RequestedRoundTrips returns count of requests that were requested by client.

func (*Stats) Snapshot added in v0.6.0

func (s *Stats) Snapshot() StatsSnapshot

Snapshot of the stats.

type StatsSnapshot added in v0.6.0

type StatsSnapshot struct {
	RequestedRoundTrips      uint64 // count of requests that were requested by client
	ActualRoundTrips         uint64 // count of requests that were actually sent
	FailedRoundTrips         uint64 // count of requests that failed
	CanceledByUserRoundTrips uint64 // count of requests that were canceled by user, using request context
	CanceledSubRequests      uint64 // count of hedged sub-requests that were canceled by transport
}

StatsSnapshot is a snapshot of Stats.

Jump to

Keyboard shortcuts

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