Commit e7c80bfc authored by hannahhoward's avatar hannahhoward

Allow randomized wait time w/o waiting

Refactor to seperate the act of waiting from reading the duration of the
next wait time, so that a calling module can use the waiting on its own

Also add a unit test
parent d0bfb593
...@@ -13,6 +13,7 @@ var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano())) ...@@ -13,6 +13,7 @@ var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano()))
type D interface { type D interface {
Set(time.Duration) time.Duration Set(time.Duration) time.Duration
Wait() Wait()
NextWaitTime() time.Duration
Get() time.Duration Get() time.Duration
} }
...@@ -35,9 +36,16 @@ func (d *delay) Set(t time.Duration) time.Duration { ...@@ -35,9 +36,16 @@ func (d *delay) Set(t time.Duration) time.Duration {
} }
func (d *delay) Wait() { func (d *delay) Wait() {
nextWaitTime := d.NextWaitTime()
d.l.RLock() d.l.RLock()
time.Sleep(nextWaitTime)
defer d.l.RUnlock() defer d.l.RUnlock()
time.Sleep(d.t) }
func (d *delay) NextWaitTime() time.Duration {
d.l.Lock()
defer d.l.Unlock()
return d.t
} }
func (d *delay) Get() time.Duration { func (d *delay) Get() time.Duration {
...@@ -68,11 +76,10 @@ type variableNormal struct { ...@@ -68,11 +76,10 @@ type variableNormal struct {
rng *rand.Rand rng *rand.Rand
} }
func (d *variableNormal) Wait() { func (d *variableNormal) NextWaitTime() time.Duration {
d.l.RLock() d.l.RLock()
defer d.l.RUnlock() defer d.l.RUnlock()
randomDelay := time.Duration(d.rng.NormFloat64() * float64(d.std)) return time.Duration(d.rng.NormFloat64()*float64(d.std)) + d.t
time.Sleep(randomDelay + d.t)
} }
// VariableUniform is a delay following a uniform distribution // VariableUniform is a delay following a uniform distribution
...@@ -97,9 +104,8 @@ type variableUniform struct { ...@@ -97,9 +104,8 @@ type variableUniform struct {
rng *rand.Rand rng *rand.Rand
} }
func (d *variableUniform) Wait() { func (d *variableUniform) NextWaitTime() time.Duration {
d.l.RLock() d.l.RLock()
defer d.l.RUnlock() defer d.l.RUnlock()
randomDelay := time.Duration(d.rng.Float64() * float64(d.d)) return time.Duration(d.rng.Float64()*float64(d.d)) + d.t
time.Sleep(randomDelay + d.t)
} }
package delay
import (
"math"
"math/rand"
"testing"
"time"
)
const testSeed = 99
func TestDelaySetAndGet(t *testing.T) {
initialValue, err := time.ParseDuration("1000ms")
if err != nil {
t.Fatal("Parse error during setup")
}
modifiedValue, err := time.ParseDuration("2000ms")
if err != nil {
t.Fatal("Parse error during setup")
}
deviation, err := time.ParseDuration("1000ms")
if err != nil {
t.Fatal("Parse error during setup")
}
fixed := Fixed(initialValue)
variableNormal := VariableNormal(initialValue, deviation, rand.New(rand.NewSource(testSeed)))
variableUniform := VariableUniform(initialValue, deviation, rand.New(rand.NewSource(testSeed)))
if fixed.Get().Seconds() != 1 {
t.Fatal("Fixed delay not initialized correctly")
}
if variableNormal.Get().Seconds() != 1 {
t.Fatal("Normalized variable delay not initialized correctly")
}
if variableUniform.Get().Seconds() != 1 {
t.Fatal("Uniform variable delay not initialized correctly")
}
fixed.Set(modifiedValue)
if fixed.Get().Seconds() != 2 {
t.Fatal("Fixed delay not set correctly")
}
variableNormal.Set(modifiedValue)
if variableNormal.Get().Seconds() != 2 {
t.Fatal("Normalized variable delay not set correctly")
}
variableUniform.Set(modifiedValue)
if variableUniform.Get().Seconds() != 2 {
t.Fatal("Uniform variable delay not initialized correctly")
}
}
func TestDelayNextWaitTime(t *testing.T) {
initialValue, err := time.ParseDuration("1000ms")
if err != nil {
t.Fatal("Parse error during setup")
}
deviation, err := time.ParseDuration("1000ms")
if err != nil {
t.Fatal("Parse error during setup")
}
fixed := Fixed(initialValue)
firstRandomNormal := rand.New(rand.NewSource(testSeed)).NormFloat64()
firstRandom := rand.New(rand.NewSource(testSeed)).Float64()
variableNormal := VariableNormal(initialValue, deviation, rand.New(rand.NewSource(testSeed)))
variableUniform := VariableUniform(initialValue, deviation, rand.New(rand.NewSource(testSeed)))
if fixed.NextWaitTime().Seconds() != 1 {
t.Fatal("Fixed delay output incorrect wait time")
}
if math.Abs(variableNormal.NextWaitTime().Seconds()-(firstRandomNormal*deviation.Seconds()+initialValue.Seconds())) > 0.00001 {
t.Fatal("Normalized variable delay output incorrect wait time")
}
if math.Abs(variableUniform.NextWaitTime().Seconds()-(firstRandom*deviation.Seconds()+initialValue.Seconds())) > 0.00001 {
t.Fatal("Uniform variable delay output incorrect wait time")
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment