generator.go 1.33 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
package delay

import (
	"math/rand"
	"time"
)

// Generator provides an interface for generating wait times
type Generator interface {
	NextWaitTime(time.Duration) time.Duration
}

var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano()))

// VariableNormalGenerator makes delays that following a normal distribution
func VariableNormalGenerator(std time.Duration, rng *rand.Rand) Generator {
	if rng == nil {
		rng = sharedRNG
	}

hannahhoward's avatar
hannahhoward committed
21
	return &variableNormal{
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
		std: std,
		rng: rng,
	}
}

type variableNormal struct {
	std time.Duration
	rng *rand.Rand
}

func (d *variableNormal) NextWaitTime(t time.Duration) time.Duration {
	return time.Duration(d.rng.NormFloat64()*float64(d.std)) + t
}

// VariableUniformGenerator generates delays following a uniform distribution
func VariableUniformGenerator(d time.Duration, rng *rand.Rand) Generator {
	if rng == nil {
		rng = sharedRNG
	}

hannahhoward's avatar
hannahhoward committed
42
	return &variableUniform{
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
		d:   d,
		rng: rng,
	}
}

type variableUniform struct {
	d   time.Duration // max delta
	rng *rand.Rand
}

func (d *variableUniform) NextWaitTime(t time.Duration) time.Duration {
	return time.Duration(d.rng.Float64()*float64(d.d)) + t
}

type fixed struct{}

// FixedGenerator returns a delay with fixed latency
func FixedGenerator() Generator {
	return &fixed{}
}

func (d *fixed) NextWaitTime(t time.Duration) time.Duration {
	return t
}