forked from alaingilbert/ogame
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
73 lines (62 loc) · 1.39 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package ogame
import (
"fmt"
"net/http"
"sync/atomic"
"time"
)
// OGameClient ...
type OGameClient struct {
http.Client
UserAgent string
rpsCounter int32
rps int32
maxRPS int32
rpsStartTime int64
}
// NewOGameClient ...
func NewOGameClient() *OGameClient {
client := &OGameClient{
Client: http.Client{
Timeout: 30 * time.Second,
},
maxRPS: 0,
}
const delay = 1
go func() {
for {
prevRPS := atomic.SwapInt32(&client.rpsCounter, 0)
atomic.StoreInt32(&client.rps, prevRPS/delay)
atomic.StoreInt64(&client.rpsStartTime, time.Now().Add(delay*time.Second).UnixNano())
time.Sleep(delay * time.Second)
}
}()
return client
}
// SetMaxRPS ...
func (c *OGameClient) SetMaxRPS(maxRPS int32) {
c.maxRPS = maxRPS
}
func (c *OGameClient) incrRPS() {
newRPS := atomic.AddInt32(&c.rpsCounter, 1)
if c.maxRPS > 0 && newRPS > c.maxRPS {
s := atomic.LoadInt64(&c.rpsStartTime) - time.Now().UnixNano()
// fmt.Printf("throttle %d\n", s)
time.Sleep(time.Duration(s))
}
}
// Do executes a request
func (c *OGameClient) Do(req *http.Request) (*http.Response, error) {
c.incrRPS()
req.Header.Add("User-Agent", c.UserAgent)
return c.Client.Do(req)
}
// FakeDo for testing purposes
func (c *OGameClient) FakeDo() {
c.incrRPS()
fmt.Println("FakeDo")
}
// GetRPS gets the current client RPS
func (c *OGameClient) GetRPS() int32 {
return atomic.LoadInt32(&c.rps)
}