Skip to content

Commit 30f2c1f

Browse files
Merge pull request #2871 from rikonor/master
Added variable latency delay, normal and uniform based
2 parents 720fa80 + cd7010f commit 30f2c1f

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

thirdparty/delay/delay.go

+61-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package delay
22

33
import (
4+
"math/rand"
45
"sync"
56
"time"
67
)
78

9+
var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano()))
10+
811
// Delay makes it easy to add (threadsafe) configurable delays to other
912
// objects.
1013
type D interface {
@@ -23,8 +26,6 @@ type delay struct {
2326
t time.Duration
2427
}
2528

26-
// TODO func Variable(time.Duration) D returns a delay with probablistic latency
27-
2829
func (d *delay) Set(t time.Duration) time.Duration {
2930
d.l.Lock()
3031
defer d.l.Unlock()
@@ -44,3 +45,61 @@ func (d *delay) Get() time.Duration {
4445
defer d.l.Unlock()
4546
return d.t
4647
}
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+
}

0 commit comments

Comments
 (0)