...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package servicemirror
17
18 import (
19 "math/rand"
20 "time"
21
22 log "github.com/sirupsen/logrus"
23 )
24
25
26 type Ticker struct {
27 C <-chan time.Time
28 stop chan bool
29 MinDuration time.Duration
30 MaxJitter time.Duration
31 }
32
33
34 func NewTicker(minDuration time.Duration, maxJitter time.Duration) *Ticker {
35 if minDuration < 0 {
36 log.WithField("duration", minDuration).Panic("Negative duration")
37 }
38 if maxJitter < 0 {
39 log.WithField("jitter", minDuration).Panic("Negative jitter")
40 }
41 c := make(chan time.Time, 1)
42 ticker := &Ticker{
43 C: c,
44 stop: make(chan bool),
45 MinDuration: minDuration,
46 MaxJitter: maxJitter,
47 }
48 go ticker.loop(c)
49 return ticker
50 }
51
52 func (t *Ticker) loop(c chan time.Time) {
53 tickLoop:
54 for {
55 time.Sleep(t.calculateDelay())
56
57 select {
58 case <-t.stop:
59 log.Info("Stopping jittered ticker")
60 close(c)
61 break tickLoop
62 case c <- time.Now():
63 default:
64 }
65 }
66 }
67
68 func (t *Ticker) calculateDelay() time.Duration {
69
70
71
72 jitter := time.Duration(rand.Int63n(int64(t.MaxJitter)))
73 delay := t.MinDuration + jitter
74 return delay
75 }
76
77
78 func (t *Ticker) Stop() {
79 t.stop <- true
80 }
81
View as plain text