generated from milosgajdos/go-repo-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: add client rate limit support (#20)
* feature: add client rate limit support You can specify your own rate limiter to limit the number of requests sent to the remote API. The easiest way is probably to use the off the shelf Limiter implemented by https://pkg.go.dev/golang.org/x/time/rate#Limiter We had to refactor the API a bit so we can wrap the http client with the provided limiter and also make room for adding retries. Signed-off-by: Milos Gajdos <[email protected]> --------- Signed-off-by: Milos Gajdos <[email protected]>
- Loading branch information
1 parent
da75163
commit eacb758
Showing
8 changed files
with
95 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
) | ||
|
||
// HTTP is a HTTP client. | ||
type HTTP struct { | ||
client *http.Client | ||
limiter Limiter | ||
} | ||
|
||
// Options are client options | ||
type Options struct { | ||
HTTPClient *http.Client | ||
Limiter Limiter | ||
} | ||
|
||
// Option is functional graph option. | ||
type Option func(*Options) | ||
|
||
// Limiter is used to apply rate limits. | ||
// NOTE: you can use off the shelf limiter from | ||
// https://pkg.go.dev/golang.org/x/time/rate#Limiter | ||
type Limiter interface { | ||
// Wait must block until limiter | ||
// permits another request to proceed. | ||
Wait(context.Context) error | ||
} | ||
|
||
// NewHTTP creates a new HTTP client and returns it. | ||
func NewHTTP(opts ...Option) *HTTP { | ||
options := Options{ | ||
HTTPClient: &http.Client{}, | ||
} | ||
for _, apply := range opts { | ||
apply(&options) | ||
} | ||
|
||
return &HTTP{ | ||
client: options.HTTPClient, | ||
limiter: options.Limiter, | ||
} | ||
} | ||
|
||
// Do dispatches the HTTP request to the network | ||
func (h *HTTP) Do(req *http.Request) (*http.Response, error) { | ||
if h.limiter != nil { | ||
err := h.limiter.Wait(req.Context()) // This is a blocking call. Honors the rate limit | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
resp, err := h.client.Do(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resp, nil | ||
} | ||
|
||
// WithHTTPClient sets the HTTP client. | ||
func WithHTTPClient(c *http.Client) Option { | ||
return func(o *Options) { | ||
o.HTTPClient = c | ||
} | ||
} | ||
|
||
// WithLimiter sets the http rate limiter. | ||
func WithLimiter(l Limiter) Option { | ||
return func(o *Options) { | ||
o.Limiter = l | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters