Skip to content

Commit

Permalink
Merge pull request #520 from essentialkaos/develop
Browse files Browse the repository at this point in the history
Version 13.11.0
  • Loading branch information
andyone authored Nov 12, 2024
2 parents 2e7a651 + 88d78a1 commit 916514c
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Changelog

### [13.11.0](https://kaos.sh/ek/13.11.0)

* `[req]` Added request limiter

### [13.10.1](https://kaos.sh/ek/13.10.1)

* `[mathutil]` Added shorthand helper `B`
Expand Down
1 change: 1 addition & 0 deletions req/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func ExampleRequest_Do() {
SetUserAgent("my-supper-app", "1.0")
SetDialTimeout(30.0)
SetRequestTimeout(30.0)
SetLimit(15.0)

resp, err := Request{
Method: GET,
Expand Down
53 changes: 53 additions & 0 deletions req/limiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package req

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2024 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import "time"

// ////////////////////////////////////////////////////////////////////////////////// //

// limiter is request limiter
type limiter struct {
lastCall time.Time
delay time.Duration
}

// ////////////////////////////////////////////////////////////////////////////////// //

// createLimiter creates new limiter
func createLimiter(rps float64) *limiter {
if rps <= 0 {
return nil
}

return &limiter{
delay: time.Duration(float64(time.Second) / rps),
}
}

// ////////////////////////////////////////////////////////////////////////////////// //

// Wait blocks current goroutine execution until next time slot become available
func (l *limiter) Wait() {
if l == nil {
return
}

if l.lastCall.IsZero() {
l.lastCall = time.Now()
return
}

w := time.Since(l.lastCall)

if w < l.delay {
time.Sleep(l.delay - w)
}

l.lastCall = time.Now()
}
25 changes: 23 additions & 2 deletions req/req.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,9 @@ type Engine struct {
Transport *http.Transport // Transport is default transport struct
Client *http.Client // Client is default client struct

dialTimeout float64 // dialTimeout is dial timeout in seconds
requestTimeout float64 // requestTimeout is request timeout in seconds
limiter *limiter // Request limiter
dialTimeout float64 // dialTimeout is dial timeout in seconds
requestTimeout float64 // requestTimeout is request timeout in seconds

initialized bool
}
Expand Down Expand Up @@ -283,6 +284,12 @@ func SetRequestTimeout(timeout float64) {
Global.SetRequestTimeout(timeout)
}

// SetLimit sets a hard limit on the number of requests per second (useful for
// working with APIs)
func SetLimit(rps float64) {
Global.SetLimit(rps)
}

// ////////////////////////////////////////////////////////////////////////////////// //

// Init initializes engine
Expand Down Expand Up @@ -423,6 +430,16 @@ func (e *Engine) SetRequestTimeout(timeout float64) {
}
}

// SetLimit sets a hard limit on the number of requests per second (useful for
// working with APIs)
func (e *Engine) SetLimit(rps float64) {
if e == nil {
return
}

e.limiter = createLimiter(rps)
}

// ////////////////////////////////////////////////////////////////////////////////// //

// Do sends request and process response
Expand Down Expand Up @@ -606,6 +623,10 @@ func (e *Engine) doRequest(r Request, method string) (*Response, error) {
return nil, err
}

if e.limiter != nil {
e.limiter.Wait()
}

resp, err := e.Client.Do(req)

if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions req/req_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func (s *ReqSuite) SetUpSuite(c *C) {

SetDialTimeout(60.0)
SetRequestTimeout(60.0)
SetLimit(1000.0)
SetUserAgent("req-test", "5", "Test/5.1.1", "Magic/4.2.1")

go runHTTPServer(s, c)
Expand Down Expand Up @@ -580,6 +581,14 @@ func (s *ReqSuite) TestQueryEncoding(c *C) {
c.Assert(qrs, Equals, "a=1&b=abcd&c&d")
}

func (s *ReqSuite) TestLimiter(c *C) {
var l *limiter

c.Assert(createLimiter(0.0), IsNil)

l.Wait()
}

func (s *ReqSuite) TestNil(c *C) {
var e *Engine

Expand All @@ -589,6 +598,7 @@ func (s *ReqSuite) TestNil(c *C) {
c.Assert(func() { e.SetUserAgent("APP", "1") }, NotPanics)
c.Assert(func() { e.SetDialTimeout(1) }, NotPanics)
c.Assert(func() { e.SetRequestTimeout(1) }, NotPanics)
c.Assert(func() { e.SetLimit(1.0) }, NotPanics)

var r *Response

Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ package ek
// ////////////////////////////////////////////////////////////////////////////////// //

// VERSION is current ek package version
const VERSION = "13.10.1"
const VERSION = "13.11.0"

0 comments on commit 916514c

Please sign in to comment.