Skip to content

Commit

Permalink
add and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
1pkg committed May 5, 2021
1 parent 013c9d1 commit 94f635a
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 7 deletions.
30 changes: 29 additions & 1 deletion README.MD
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Hedgehog: seamless http hedged requests for go
<p align="center">
<img src="https://raw.githubusercontent.com/1pkg/hedgehog/master/gopher.png" alt="gohalt"/>
</p>

# Hedgehog 🦔: http hedged transport in go

[![lint](https://github.com/1pkg/hedgehog/workflows/lint/badge.svg)](https://github.com/1pkg/hedgehog/actions?query=workflow%3Alint+branch%3Amaster+)
[![build](https://github.com/1pkg/hedgehog/workflows/build/badge.svg)](https://github.com/1pkg/hedgehog/actions?query=workflow%3Abuild+branch%3Amaster+)
Expand All @@ -10,6 +14,30 @@

## Details

Hedgehog provides hedged http transport decorator to reduce [tail latency at scale](https://cacm.acm.org/magazines/2013/2/160173-the-tail-at-scale/fulltext). Hedged transport makes hedged http calls for matching http resource up to calls+1 times, where initial http call starts right away and then all hedged calls start together after delay calculated by resource. Hedged transport processes and returns first successful http response all other requests in flight are canceled, in case all hedged response failed it simply returns first occurred error. If no matching resources were found - hedged transport simply calls underlying transport.

```go
hedgehog.NewHTTPClient(
http.DefaultClient,
// will initiate 2+1 hedged http request.
2,
// for GET /profile/[0-9] initiate hedged request only after flat 1ms.
NewResourceStatic(http.MethodGet, regexp.MustCompile(`profile/[0-9]`), ms_1, http.StatusOK),
// for POST /profile initiate hedged request starting with flat 5ms, but after 40/4 calls use aggregated average latency.
NewResourceAverage(http.MethodPost, regexp.MustCompile(`profile`), ms_5, 40, http.StatusOK),
// for Delete /profile initiate hedged request starting with flat 5ms, but after 50/2 calls use aggregated p30 latency.
NewResourcePercentiles(http.MethodDelete, regexp.MustCompile(`profile`), ms_5, 0.3, 50, http.StatusOK),
).Get("http://example.com/profile/5")
```

There are multiple different http hedged resource types to control hedging behavior.

| Resource | Definition | Description |
|---|---|---|
| static | `func NewResourceStatic(method string, url *regexp.Regexp, delay time.Duration, allowedCodes ...int) Resource` | Returned resource always waits for static specified delay.<br> The resource matches each request against both provided http method and full url regexp.<br> The resource checks if response result http code is included in provided allowed codes, if it is not it returnes `ErrResourceUnexpectedResponseCode`. |
| average | `func NewResourceAverage(method string, url *regexp.Regexp, delay time.Duration, capacity int, allowedCodes ...int) Resource` | Returned resource dynamically adjusts wait delay based on received successful responses average delays.<br> The resource is starting to use dynamically adjusted wait delay only after capacity/4 calls.<br> The resource matches each request against both provided http method and full url regexp.<br> The resource checks if response result http code is included in provided allowed codes, if it is not it returnes `ErrResourceUnexpectedResponseCode`. |
| percentiles | `func NewResourcePercentiles(method string, url *regexp.Regexp, delay time.Duration, percentile float64, capacity int, allowedCodes ...int) Resource` | Returned resource dynamically adjusts wait delay based on received successful responses delays percentiles.<br> The resource is starting to use dynamically adjusted wait delay only after capacity/2 calls, if more than provided capacity calls were received, first half of delay percentiles buffer will be flushed.<br> Returned resource matches each request against both provided http method and full url regexp.<br> Returned resource checks if response result http code is included in provided allowed codes, if it is not it returnes `ErrResourceUnexpectedResponseCode`. |

## Licence

Hedgehog is licensed under the MIT License.
Expand Down
Binary file added gopher.kra
Binary file not shown.
Binary file added gopher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ type average struct {
capacity int64
}

// NewResourceAverage returns new resource instance that dynamically adjust wait delay based on
// NewResourceAverage returns new resource instance that dynamically adjusts wait delay based on
// received successful responses average delays.
// Returned resource is starting to use dynamically adjusted wait delay only after capacity/4 calls.
// Returned resource matches each request against both provided http method and full url regexp.
Expand Down Expand Up @@ -138,7 +138,7 @@ type percentiles struct {
lock sync.RWMutex
}

// NewResourcePercentiles returns new resource instance that dynamically adjust wait delay based on
// NewResourcePercentiles returns new resource instance that dynamically adjusts wait delay based on
// received successful responses delays percentiles.
// Returned resource is starting to use dynamically adjusted wait delay only after capacity/2 calls,
// if more than provided capacity calls were received, first half of delay percentiles buffer will be flushed.
Expand Down
8 changes: 4 additions & 4 deletions transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ type transport struct {
}

// NewRoundTripper returns new http hedged transport with provided resources.
// Returned transport will make hedged http calls in case of resource matching http request up to calls+1 times,
// Returned transport makes hedged http calls in case of resource matching http request up to calls+1 times,
// original http call starts right away and then all hedged calls start together after delay specified by resource.
// Returned transport will process and return first successful http response, in case all hedged response failed
// it will simply return first occurred error.
// If no matching resource were found - the transport will simply call underlying transport.
// Returned transport processes and returns first successful http response all other requests in flight are canceled,
// in case all hedged response failed it simply returns first occurred error.
// If no matching resources were found - the transport simply calls underlying transport.
func NewRoundTripper(internal http.RoundTripper, calls uint64, resources ...Resource) http.RoundTripper {
return transport{internal: internal, calls: calls, resources: resources}
}
Expand Down

0 comments on commit 94f635a

Please sign in to comment.