Skip to content
This repository was archived by the owner on Apr 19, 2024. It is now read-only.

Commit 632440f

Browse files
committed
Now using holster clock instead of time for most time calculations
1 parent d7efdde commit 632440f

19 files changed

+135
-129
lines changed

algorithms.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ limitations under the License.
1717
package gubernator
1818

1919
import (
20-
"time"
20+
"github.com/mailgun/holster/v3/clock"
2121
)
2222

2323
// Implements token bucket algorithm for rate limiting. https://en.wikipedia.org/wiki/Token_bucket
@@ -88,7 +88,7 @@ func tokenBucket(s Store, c Cache, r *RateLimitReq) (resp *RateLimitResp, err er
8888
if t.Duration != r.Duration {
8989
expire := t.CreatedAt + r.Duration
9090
if HasBehavior(r.Behavior, Behavior_DURATION_IS_GREGORIAN) {
91-
expire, err = GregorianExpiration(time.Now(), r.Duration)
91+
expire, err = GregorianExpiration(clock.Now(), r.Duration)
9292
if err != nil {
9393
return nil, err
9494
}
@@ -138,7 +138,7 @@ func tokenBucket(s Store, c Cache, r *RateLimitReq) (resp *RateLimitResp, err er
138138
now := MillisecondNow()
139139
expire := now + r.Duration
140140
if HasBehavior(r.Behavior, Behavior_DURATION_IS_GREGORIAN) {
141-
expire, err = GregorianExpiration(time.Now(), r.Duration)
141+
expire, err = GregorianExpiration(clock.Now(), r.Duration)
142142
if err != nil {
143143
return nil, err
144144
}
@@ -214,11 +214,11 @@ func leakyBucket(s Store, c Cache, r *RateLimitReq) (resp *RateLimitResp, err er
214214
duration := r.Duration
215215
rate := float64(duration) / float64(r.Limit)
216216
if HasBehavior(r.Behavior, Behavior_DURATION_IS_GREGORIAN) {
217-
d, err := GregorianDuration(time.Now(), r.Duration)
217+
d, err := GregorianDuration(clock.Now(), r.Duration)
218218
if err != nil {
219219
return nil, err
220220
}
221-
n := time.Now()
221+
n := clock.Now()
222222
expire, err := GregorianExpiration(n, r.Duration)
223223
if err != nil {
224224
return nil, err
@@ -291,7 +291,7 @@ func leakyBucket(s Store, c Cache, r *RateLimitReq) (resp *RateLimitResp, err er
291291

292292
duration := r.Duration
293293
if HasBehavior(r.Behavior, Behavior_DURATION_IS_GREGORIAN) {
294-
n := time.Now()
294+
n := clock.Now()
295295
expire, err := GregorianExpiration(n, r.Duration)
296296
if err != nil {
297297
return nil, err

cache.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ package gubernator
2121
import (
2222
"container/list"
2323
"sync"
24-
"time"
2524

25+
"github.com/mailgun/holster/v3/clock"
2626
"github.com/mailgun/holster/v3/setter"
2727
"github.com/prometheus/client_golang/prometheus"
2828
)
@@ -131,7 +131,7 @@ func (c *LRUCache) Add(record *CacheItem) bool {
131131

132132
// Return unix epoch in milliseconds
133133
func MillisecondNow() int64 {
134-
return time.Now().UnixNano() / 1000000
134+
return clock.Now().UnixNano() / 1000000
135135
}
136136

137137
// GetItem returns the item stored in the cache

client.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package gubernator
1818

1919
import (
2020
"math/rand"
21-
"time"
2221

22+
"github.com/mailgun/holster/v3/clock"
2323
"github.com/pkg/errors"
2424
"google.golang.org/grpc"
2525
)
@@ -48,18 +48,18 @@ func DialV1Server(server string) (V1Client, error) {
4848
return NewV1Client(conn), nil
4949
}
5050

51-
// Convert a time.Duration to a unix millisecond timestamp
52-
func ToTimeStamp(duration time.Duration) int64 {
53-
return int64(duration / time.Millisecond)
51+
// Convert a clock.Duration to a unix millisecond timestamp
52+
func ToTimeStamp(duration clock.Duration) int64 {
53+
return int64(duration / clock.Millisecond)
5454
}
5555

5656
// Convert a unix millisecond timestamp to a time.Duration
57-
func FromTimeStamp(ts int64) time.Duration {
58-
return time.Now().Sub(FromUnixMilliseconds(ts))
57+
func FromTimeStamp(ts int64) clock.Duration {
58+
return clock.Now().Sub(FromUnixMilliseconds(ts))
5959
}
6060

61-
func FromUnixMilliseconds(ts int64) time.Time {
62-
return time.Unix(0, ts*int64(time.Millisecond))
61+
func FromUnixMilliseconds(ts int64) clock.Time {
62+
return clock.Unix(0, ts*int64(clock.Millisecond))
6363
}
6464

6565
// Given a list of peers, return a random peer

cluster/cluster.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ package cluster
1919
import (
2020
"context"
2121
"math/rand"
22-
"time"
2322

2423
"github.com/mailgun/gubernator"
24+
"github.com/mailgun/holster/v3/clock"
2525
"github.com/pkg/errors"
2626
"github.com/sirupsen/logrus"
2727
)
@@ -76,17 +76,17 @@ func Restart(ctx context.Context) {
7676
// Start a local cluster with specific addresses
7777
func StartWith(localPeers []gubernator.PeerInfo) error {
7878
for _, peer := range localPeers {
79-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
79+
ctx, cancel := context.WithTimeout(context.Background(), clock.Second*10)
8080
d, err := gubernator.SpawnDaemon(ctx, gubernator.DaemonConfig{
8181
Logger: logrus.WithField("instance", peer.GRPCAddress),
8282
GRPCListenAddress: peer.GRPCAddress,
8383
HTTPListenAddress: peer.HTTPAddress,
8484
Behaviors: gubernator.BehaviorConfig{
8585
// Suitable for testing but not production
86-
GlobalSyncWait: time.Millisecond * 50,
87-
GlobalTimeout: time.Second * 5,
88-
BatchTimeout: time.Second * 5,
89-
MultiRegionTimeout: time.Second * 5,
86+
GlobalSyncWait: clock.Millisecond * 50,
87+
GlobalTimeout: clock.Second * 5,
88+
BatchTimeout: clock.Second * 5,
89+
MultiRegionTimeout: clock.Second * 5,
9090
},
9191
})
9292
cancel()

cmd/gubernator-cli/main.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import (
2121
"fmt"
2222
"math/rand"
2323
"os"
24-
"time"
2524

2625
"github.com/davecgh/go-spew/spew"
2726
guber "github.com/mailgun/gubernator"
27+
"github.com/mailgun/holster/v3/clock"
2828
"github.com/mailgun/holster/v3/syncutil"
2929
)
3030

@@ -57,7 +57,7 @@ func main() {
5757
UniqueKey: guber.RandomString(10),
5858
Hits: 1,
5959
Limit: randInt(1, 10),
60-
Duration: randInt(int(time.Millisecond*500), int(time.Second*6)),
60+
Duration: randInt(int(clock.Millisecond*500), int(clock.Second*6)),
6161
Algorithm: guber.Algorithm_TOKEN_BUCKET,
6262
})
6363
}
@@ -67,7 +67,7 @@ func main() {
6767
for _, rateLimit := range rateLimits {
6868
fan.Run(func(obj interface{}) error {
6969
r := obj.(*guber.RateLimitReq)
70-
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500)
70+
ctx, cancel := context.WithTimeout(context.Background(), clock.Millisecond*500)
7171
// Now hit our cluster with the rate limits
7272
resp, err := client.GetRateLimits(ctx, &guber.GetRateLimitsReq{
7373
Requests: []*guber.RateLimitReq{r},

cmd/gubernator/main.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ import (
2929
"runtime"
3030
"strconv"
3131
"strings"
32-
"time"
3332

3433
etcd "github.com/coreos/etcd/clientv3"
3534
"github.com/davecgh/go-spew/spew"
3635
"github.com/mailgun/gubernator"
36+
"github.com/mailgun/holster/v3/clock"
3737
"github.com/mailgun/holster/v3/setter"
3838
"github.com/mailgun/holster/v3/slice"
3939
"github.com/pkg/errors"
@@ -59,7 +59,7 @@ func main() {
5959
conf, err := confFromFile(configFile)
6060
checkErr(err, "while getting config")
6161

62-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
62+
ctx, cancel := context.WithTimeout(context.Background(), clock.Second*10)
6363
defer cancel()
6464

6565
// Start the daemon
@@ -142,7 +142,7 @@ func confFromFile(configFile string) (gubernator.DaemonConfig, error) {
142142
setter.SetDefault(&conf.EtcdPoolConf.KeyPrefix, os.Getenv("GUBER_ETCD_KEY_PREFIX"), "/gubernator-peers")
143143
setter.SetDefault(&conf.EtcdPoolConf.EtcdConfig, &etcd.Config{})
144144
setter.SetDefault(&conf.EtcdPoolConf.EtcdConfig.Endpoints, getEnvSlice("GUBER_ETCD_ENDPOINTS"), []string{"localhost:2379"})
145-
setter.SetDefault(&conf.EtcdPoolConf.EtcdConfig.DialTimeout, getEnvDuration("GUBER_ETCD_DIAL_TIMEOUT"), time.Second*5)
145+
setter.SetDefault(&conf.EtcdPoolConf.EtcdConfig.DialTimeout, getEnvDuration("GUBER_ETCD_DIAL_TIMEOUT"), clock.Second*5)
146146
setter.SetDefault(&conf.EtcdPoolConf.EtcdConfig.Username, os.Getenv("GUBER_ETCD_USER"))
147147
setter.SetDefault(&conf.EtcdPoolConf.EtcdConfig.Password, os.Getenv("GUBER_ETCD_PASSWORD"))
148148
setter.SetDefault(&conf.EtcdPoolConf.AdvertiseAddress, os.Getenv("GUBER_ETCD_ADVERTISE_ADDRESS"), conf.AdvertiseAddress)
@@ -319,12 +319,12 @@ func getEnvInteger(name string) int {
319319
return int(i)
320320
}
321321

322-
func getEnvDuration(name string) time.Duration {
322+
func getEnvDuration(name string) clock.Duration {
323323
v := os.Getenv(name)
324324
if v == "" {
325325
return 0
326326
}
327-
d, err := time.ParseDuration(v)
327+
d, err := clock.ParseDuration(v)
328328
if err != nil {
329329
log.WithError(err).Errorf("while parsing '%s' as a duration", name)
330330
return 0

etcd.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ package gubernator
1919
import (
2020
"context"
2121
"encoding/json"
22-
"time"
2322

2423
etcd "github.com/coreos/etcd/clientv3"
24+
"github.com/mailgun/holster/v3/clock"
2525
"github.com/mailgun/holster/v3/setter"
2626
"github.com/mailgun/holster/v3/syncutil"
2727
"github.com/pkg/errors"
2828
"github.com/sirupsen/logrus"
2929
)
3030

3131
const (
32-
etcdTimeout = time.Second * 10
33-
backOffTimeout = time.Second * 5
32+
etcdTimeout = clock.Second * 10
33+
backOffTimeout = clock.Second * 5
3434
leaseTTL = 30
3535
defaultBaseKey = "/gubernator/peers/"
3636
)
@@ -135,7 +135,7 @@ func (e *EtcdPool) watchPeers() error {
135135
select {
136136
case <-ready:
137137
e.log.Infof("watching for peer changes '%s' at revision %d", e.conf.KeyPrefix, revision)
138-
case <-time.After(etcdTimeout):
138+
case <-clock.After(etcdTimeout):
139139
return errors.New("timed out while waiting for watcher.Watch() to start")
140140
}
141141
return nil
@@ -221,7 +221,7 @@ func (e *EtcdPool) watch() error {
221221
e.log.WithError(err).
222222
Error("while attempting to restart watch")
223223
select {
224-
case <-time.After(backOffTimeout):
224+
case <-clock.After(backOffTimeout):
225225
return true
226226
case <-done:
227227
return false
@@ -269,7 +269,7 @@ func (e *EtcdPool) register(name string) error {
269269
return nil
270270
}
271271

272-
var lastKeepAlive time.Time
272+
var lastKeepAlive clock.Time
273273

274274
// Attempt to register our instance with etcd
275275
if err = register(); err != nil {
@@ -283,7 +283,7 @@ func (e *EtcdPool) register(name string) error {
283283
e.log.WithError(err).
284284
Error("while attempting to re-register peer")
285285
select {
286-
case <-time.After(backOffTimeout):
286+
case <-clock.After(backOffTimeout):
287287
return true
288288
case <-done:
289289
return false
@@ -306,12 +306,12 @@ func (e *EtcdPool) register(name string) error {
306306
}
307307

308308
// Ensure we are getting keep alive's regularly
309-
if lastKeepAlive.Sub(time.Now()) > time.Second*leaseTTL {
309+
if lastKeepAlive.Sub(clock.Now()) > clock.Second*leaseTTL {
310310
e.log.Warn("to long between keep alive heartbeats, re-registering peer")
311311
keepAlive = nil
312312
return true
313313
}
314-
lastKeepAlive = time.Now()
314+
lastKeepAlive = clock.Now()
315315
case <-done:
316316
ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout)
317317
if _, err := e.conf.Client.Delete(ctx, instanceKey); err != nil {

0 commit comments

Comments
 (0)