durations are now optionally spans for jitter

This commit is contained in:
Bel LaPointe
2022-01-11 07:39:24 -05:00
parent 31a3d4948b
commit 6c455764e1
4 changed files with 149 additions and 11 deletions

View File

@@ -2,17 +2,29 @@ package config
import (
"encoding/json"
"errors"
"math/rand"
"strings"
"time"
)
type Duration time.Duration
type Duration struct {
least time.Duration
most time.Duration
}
func (d Duration) Get() time.Duration {
return time.Duration(d)
jitter := d.most - d.least
if jitter >= time.Second {
jitter = time.Second * time.Duration(rand.Int()%int(jitter.Seconds()))
} else {
jitter = 0
}
return time.Duration(d.least + jitter)
}
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.Get().String())
return json.Marshal(d.least.String() + ".." + d.most.String())
}
func (d *Duration) UnmarshalJSON(b []byte) error {
@@ -20,10 +32,25 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &s); err != nil {
return err
}
d2, err := time.ParseDuration(s)
if !strings.Contains(s, "..") {
s = s + ".." + s
}
splits := strings.Split(s, "..")
if len(splits) != 2 {
return errors.New("unexpected ..")
}
least, err := time.ParseDuration(splits[0])
if err != nil {
return err
}
*d = Duration(d2)
most, err := time.ParseDuration(splits[1])
if err != nil {
return err
}
if least > most {
most, least = least, most
}
d.most = most
d.least = least
return nil
}