diff --git a/pkg/services/ticker.go b/pkg/services/ticker.go new file mode 100644 index 000000000..1cff62c35 --- /dev/null +++ b/pkg/services/ticker.go @@ -0,0 +1,40 @@ +package services + +import ( + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/utils" +) + +// Ticker is like time.Ticker, but with two differences: +// - the first tick is fired immediately +// - each period has jitter applied by utils.WithJitter. +type Ticker struct { + C <-chan time.Time + stop StopChan +} + +func (t *Ticker) Stop() { close(t.stop) } + +// NewTicker returns a new Ticker with a period of d. +func NewTicker(d time.Duration) *Ticker { + c := make(chan time.Time) // unbuffered so we block and delay if not being handled + t := Ticker{C: c, stop: make(StopChan)} + go func() { + c <- time.Now() + for { + select { + case <-t.stop: + return + + case <-time.After(utils.WithJitter(d)): + select { + case <-t.stop: + return + case c <- time.Now(): + } + } + } + }() + return &t +}