From 564c8d6fed4e27480b32174e33c431e21e6f76e6 Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Wed, 22 Dec 2021 16:30:35 +0100 Subject: [PATCH] Remove time package Signed-off-by: Arve Knudsen --- CHANGELOG.md | 1 + ring/basic_lifecycler.go | 7 +- ring/lifecycler.go | 5 +- ring/ticker.go | 14 ++++ ring/ticker_test.go | 34 ++++++++++ time/time.go | 96 -------------------------- time/time_test.go | 141 --------------------------------------- 7 files changed, 54 insertions(+), 244 deletions(-) create mode 100644 ring/ticker.go create mode 100644 ring/ticker_test.go delete mode 100644 time/time.go delete mode 100644 time/time_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c67e36ee..2be12a7f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * [CHANGE] The `status_code` label on gRPC client metrics has changed from '200' and '500' to '2xx', '5xx', '4xx', 'cancel' or 'error'. #68 * [CHANGE] Memberlist: changed probe interval from `1s` to `5s` and probe timeout from `500ms` to `2s`. #90 * [CHANGE] Remove package `math`. #104 +* [CHANGE] time: Remove time package. #103 * [ENHANCEMENT] Add middleware package. #38 * [ENHANCEMENT] Add the ring package #45 * [ENHANCEMENT] Add limiter package. #41 diff --git a/ring/basic_lifecycler.go b/ring/basic_lifecycler.go index 96186acd0..726a85430 100644 --- a/ring/basic_lifecycler.go +++ b/ring/basic_lifecycler.go @@ -14,7 +14,6 @@ import ( "github.com/grafana/dskit/kv" "github.com/grafana/dskit/services" - dstime "github.com/grafana/dskit/time" ) type BasicLifecyclerDelegate interface { @@ -186,7 +185,7 @@ func (l *BasicLifecycler) starting(ctx context.Context) error { } func (l *BasicLifecycler) running(ctx context.Context) error { - heartbeatTickerStop, heartbeatTickerChan := dstime.NewDisableableTicker(l.cfg.HeartbeatPeriod) + heartbeatTickerStop, heartbeatTickerChan := newDisableableTicker(l.cfg.HeartbeatPeriod) defer heartbeatTickerStop() for { @@ -218,7 +217,7 @@ func (l *BasicLifecycler) stopping(runningError error) error { }() // Heartbeat while the stopping delegate function is running. - heartbeatTickerStop, heartbeatTickerChan := dstime.NewDisableableTicker(l.cfg.HeartbeatPeriod) + heartbeatTickerStop, heartbeatTickerChan := newDisableableTicker(l.cfg.HeartbeatPeriod) defer heartbeatTickerStop() heartbeatLoop: @@ -300,7 +299,7 @@ func (l *BasicLifecycler) registerInstance(ctx context.Context) error { } func (l *BasicLifecycler) waitStableTokens(ctx context.Context, period time.Duration) error { - heartbeatTickerStop, heartbeatTickerChan := dstime.NewDisableableTicker(l.cfg.HeartbeatPeriod) + heartbeatTickerStop, heartbeatTickerChan := newDisableableTicker(l.cfg.HeartbeatPeriod) defer heartbeatTickerStop() // The first observation will occur after the specified period. diff --git a/ring/lifecycler.go b/ring/lifecycler.go index 525a2b16a..be103e1fb 100644 --- a/ring/lifecycler.go +++ b/ring/lifecycler.go @@ -19,7 +19,6 @@ import ( "github.com/grafana/dskit/flagext" "github.com/grafana/dskit/kv" "github.com/grafana/dskit/services" - dstime "github.com/grafana/dskit/time" ) // LifecyclerConfig is the config to build a Lifecycler. @@ -403,7 +402,7 @@ func (i *Lifecycler) loop(ctx context.Context) error { autoJoinAfter := time.After(i.cfg.JoinAfter) var observeChan <-chan time.Time - heartbeatTickerStop, heartbeatTickerChan := dstime.NewDisableableTicker(i.cfg.HeartbeatPeriod) + heartbeatTickerStop, heartbeatTickerChan := newDisableableTicker(i.cfg.HeartbeatPeriod) defer heartbeatTickerStop() for { @@ -480,7 +479,7 @@ func (i *Lifecycler) stopping(runningError error) error { return nil } - heartbeatTickerStop, heartbeatTickerChan := dstime.NewDisableableTicker(i.cfg.HeartbeatPeriod) + heartbeatTickerStop, heartbeatTickerChan := newDisableableTicker(i.cfg.HeartbeatPeriod) defer heartbeatTickerStop() // Mark ourselved as Leaving so no more samples are send to us. diff --git a/ring/ticker.go b/ring/ticker.go new file mode 100644 index 000000000..1d854472b --- /dev/null +++ b/ring/ticker.go @@ -0,0 +1,14 @@ +package ring + +import "time" + +// newDisableableTicker essentially wraps NewTicker but allows the ticker to be disabled by passing +// zero duration as the interval. Returns a function for stopping the ticker, and the ticker channel. +func newDisableableTicker(interval time.Duration) (func(), <-chan time.Time) { + if interval == 0 { + return func() {}, nil + } + + tick := time.NewTicker(interval) + return func() { tick.Stop() }, tick.C +} diff --git a/ring/ticker_test.go b/ring/ticker_test.go new file mode 100644 index 000000000..81fe6cf21 --- /dev/null +++ b/ring/ticker_test.go @@ -0,0 +1,34 @@ +package ring + +import ( + "testing" + "time" +) + +func TestNewDisableableTicker_Enabled(t *testing.T) { + stop, ch := newDisableableTicker(10 * time.Millisecond) + defer stop() + + time.Sleep(100 * time.Millisecond) + + select { + case <-ch: + break + default: + t.Error("ticker should have ticked when enabled") + } +} + +func TestNewDisableableTicker_Disabled(t *testing.T) { + stop, ch := newDisableableTicker(0) + defer stop() + + time.Sleep(100 * time.Millisecond) + + select { + case <-ch: + t.Error("ticker should not have ticked when disabled") + default: + break + } +} diff --git a/time/time.go b/time/time.go deleted file mode 100644 index 84c698a18..000000000 --- a/time/time.go +++ /dev/null @@ -1,96 +0,0 @@ -package time - -import ( - "math" - "math/rand" - "net/http" - "strconv" - "time" - - "github.com/prometheus/common/model" - "github.com/weaveworks/common/httpgrpc" -) - -const ( - nanosecondsInMillisecond = int64(time.Millisecond / time.Nanosecond) -) - -func ToMillis(t time.Time) int64 { - return t.UnixNano() / nanosecondsInMillisecond -} - -// FromMillis is a helper to turn milliseconds -> time.Time -func FromMillis(ms int64) time.Time { - return time.Unix(0, ms*nanosecondsInMillisecond) -} - -// FormatTimeMillis returns a human readable version of the input time (in milliseconds). -func FormatTimeMillis(ms int64) string { - return FromMillis(ms).String() -} - -// FormatTimeModel returns a human readable version of the input time. -func FormatTimeModel(t model.Time) string { - return FromMillis(int64(t)).String() -} - -// ParseTime parses the string into an int64, milliseconds since epoch. -func ParseTime(s string) (int64, error) { - if t, err := strconv.ParseFloat(s, 64); err == nil { - s, ns := math.Modf(t) - ns = math.Round(ns*1000) / 1000 - tm := time.Unix(int64(s), int64(ns*float64(time.Second))) - return ToMillis(tm), nil - } - if t, err := time.Parse(time.RFC3339Nano, s); err == nil { - return ToMillis(t), nil - } - return 0, httpgrpc.Errorf(http.StatusBadRequest, "cannot parse %q to a valid timestamp", s) -} - -// DurationWithJitter returns random duration from "input - input*variance" to "input + input*variance" interval. -func DurationWithJitter(input time.Duration, variancePerc float64) time.Duration { - // No duration? No jitter. - if input == 0 { - return 0 - } - - variance := int64(float64(input) * variancePerc) - if variance == 0 { - // Values too low - return input - } - - jitter := rand.Int63n(variance*2) - variance - - return input + time.Duration(jitter) -} - -// DurationWithPositiveJitter returns random duration from "input" to "input + input*variance" interval. -func DurationWithPositiveJitter(input time.Duration, variancePerc float64) time.Duration { - // No duration? No jitter. - if input == 0 { - return 0 - } - - variance := int64(float64(input) * variancePerc) - if variance == 0 { - // Values too low - return input - } - - jitter := rand.Int63n(variance) - - return input + time.Duration(jitter) -} - -// NewDisableableTicker essentially wraps NewTicker but allows the ticker to be disabled by passing -// zero duration as the interval. Returns a function for stopping the ticker, and the ticker channel. -func NewDisableableTicker(interval time.Duration) (func(), <-chan time.Time) { - if interval == 0 { - return func() {}, nil - } - - tick := time.NewTicker(interval) - return func() { tick.Stop() }, tick.C -} diff --git a/time/time_test.go b/time/time_test.go deleted file mode 100644 index ee94c4b49..000000000 --- a/time/time_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package time - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestTimeFromMillis(t *testing.T) { - testExpr := []struct { - input int64 - expected time.Time - }{ - {input: 1000, expected: time.Unix(1, 0)}, - {input: 1500, expected: time.Unix(1, 500*nanosecondsInMillisecond)}, - } - - for i, c := range testExpr { - t.Run(fmt.Sprint(i), func(t *testing.T) { - res := FromMillis(c.input) - require.Equal(t, c.expected, res) - }) - } -} - -func TestDurationWithJitter(t *testing.T) { - const numRuns = 1000 - - for i := 0; i < numRuns; i++ { - actual := DurationWithJitter(time.Minute, 0.5) - assert.GreaterOrEqual(t, int64(actual), int64(30*time.Second)) - assert.LessOrEqual(t, int64(actual), int64(90*time.Second)) - } -} - -func TestDurationWithJitter_ZeroInputDuration(t *testing.T) { - assert.Equal(t, time.Duration(0), DurationWithJitter(time.Duration(0), 0.5)) -} - -func TestDurationWithJitter_VeryLowDuration(t *testing.T) { - assert.Equal(t, 4*time.Nanosecond, DurationWithJitter(4*time.Nanosecond, 0.2)) -} - -func TestDurationWithPositiveJitter(t *testing.T) { - const numRuns = 1000 - - for i := 0; i < numRuns; i++ { - actual := DurationWithPositiveJitter(time.Minute, 0.5) - assert.GreaterOrEqual(t, int64(actual), int64(60*time.Second)) - assert.LessOrEqual(t, int64(actual), int64(90*time.Second)) - } -} - -func TestDurationWithPositiveJitter_ZeroInputDuration(t *testing.T) { - assert.Equal(t, time.Duration(0), DurationWithPositiveJitter(time.Duration(0), 0.5)) -} - -func TestDurationWithPositiveJitter_VeryLowDuration(t *testing.T) { - assert.Equal(t, time.Nanosecond, DurationWithPositiveJitter(time.Nanosecond, 0.5)) -} - -func TestParseTime(t *testing.T) { - tests := []struct { - input string - fail bool - result time.Time - }{ - { - input: "", - fail: true, - }, { - input: "abc", - fail: true, - }, { - input: "30s", - fail: true, - }, { - input: "123", - result: time.Unix(123, 0), - }, { - input: "123.123", - result: time.Unix(123, 123000000), - }, { - input: "2015-06-03T13:21:58.555Z", - result: time.Unix(1433337718, 555*time.Millisecond.Nanoseconds()), - }, { - input: "2015-06-03T14:21:58.555+01:00", - result: time.Unix(1433337718, 555*time.Millisecond.Nanoseconds()), - }, { - // Test nanosecond rounding. - input: "2015-06-03T13:21:58.56789Z", - result: time.Unix(1433337718, 567*1e6), - }, { - // Test float rounding. - input: "1543578564.705", - result: time.Unix(1543578564, 705*1e6), - }, - } - - for _, test := range tests { - ts, err := ParseTime(test.input) - if test.fail { - require.Error(t, err) - continue - } - - require.NoError(t, err) - assert.Equal(t, ToMillis(test.result), ts) - } -} - -func TestNewDisableableTicker_Enabled(t *testing.T) { - stop, ch := NewDisableableTicker(10 * time.Millisecond) - defer stop() - - time.Sleep(100 * time.Millisecond) - - select { - case <-ch: - break - default: - t.Error("ticker should have ticked when enabled") - } -} - -func TestNewDisableableTicker_Disabled(t *testing.T) { - stop, ch := NewDisableableTicker(0) - defer stop() - - time.Sleep(100 * time.Millisecond) - - select { - case <-ch: - t.Error("ticker should not have ticked when disabled") - default: - break - } -}