@cryptotaxi247 / kubo / commits / cd7010f7b

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 +}