Added variable latency delay, normal and uniform based
- Allow providing new delays with your own rng / use shared rng License: MIT Signed-off-by: Or Rikon <rikonor@gmail.com>
Or Rikon committed
Jun 18, 2016 at 11:04 UTC
cd7010f7bf5638be97d00c262e18fe995ebbb6f6
1 file changed
+61
-2
thirdparty/delay/delay.go
+61
-2
@@ -1,10 +1,13 @@
1
package delay
2
3
import (
4
+ "math/rand"
5
"sync"
6
"time"
7
)
8
9
+var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano()))
10
+
11
// Delay makes it easy to add (threadsafe) configurable delays to other
12
// objects.
13
type D interface {
@@ -23,8 +26,6 @@ type delay struct {
26
t time.Duration
27
}
28
26
-// TODO func Variable(time.Duration) D returns a delay with probablistic latency
27
-
29
func (d *delay) Set(t time.Duration) time.Duration {
30
d.l.Lock()
31
defer d.l.Unlock()
@@ -44,3 +45,61 @@ func (d *delay) Get() time.Duration {
45
defer d.l.Unlock()
46
return d.t
47
}
48
+
49
+// VariableNormal is a delay following a normal distribution
50
+// Notice that to implement the D interface Set can only change the mean delay
51
+// the standard deviation is set only at initialization
52
+func VariableNormal(t, std time.Duration, rng *rand.Rand) D {
53
+ if rng == nil {
54
+ rng = sharedRNG
55
+ }
56
+
57
+ v := &variableNormal{
58
+ std: std,
59
+ rng: rng,
60
+ }
61
+ v.t = t
62
+ return v
63
+}
64
+
65
+type variableNormal struct {
66
+ delay
67
+ std time.Duration
68
+ rng *rand.Rand
69
+}
70
+
71
+func (d *variableNormal) Wait() {
72
+ d.l.RLock()
73
+ defer d.l.RUnlock()
74
+ randomDelay := time.Duration(d.rng.NormFloat64() * float64(d.std))
75
+ time.Sleep(randomDelay + d.t)
76
+}
77
+
78
+// VariableUniform is a delay following a uniform distribution
79
+// Notice that to implement the D interface Set can only change the minimum delay
80
+// the delta is set only at initialization
81
+func VariableUniform(t, d time.Duration, rng *rand.Rand) D {
82
+ if rng == nil {
83
+ rng = sharedRNG
84
+ }
85
+
86
+ v := &variableUniform{
87
+ d: d,
88
+ rng: rng,
89
+ }
90
+ v.t = t
91
+ return v
92
+}
93
+
94
+type variableUniform struct {
95
+ delay
96
+ d time.Duration // max delta
97
+ rng *rand.Rand
98
+}
99
+
100
+func (d *variableUniform) Wait() {
101
+ d.l.RLock()
102
+ defer d.l.RUnlock()
103
+ randomDelay := time.Duration(d.rng.Float64() * float64(d.d))
104
+ time.Sleep(randomDelay + d.t)
105
+}