jitter: add NewTickerContext

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
2022-03-26 17:59:19 +03:00
parent 297a80da84
commit c6c2b0884e
4 changed files with 123 additions and 3 deletions

View File

@@ -1,6 +1,7 @@
package jitter
package jitter // import "go.unistack.org/micro/v3/util/jitter"
import (
"context"
"time"
"go.unistack.org/micro/v3/util/rand"
@@ -10,13 +11,31 @@ import (
// the min and max duration values (stored internally as int64 nanosecond
// counts).
type Ticker struct {
C chan time.Time
ctx context.Context
done chan chan struct{}
C chan time.Time
min int64
max int64
exp int64
exit bool
rng rand.Rand
}
// NewTickerContext returns a pointer to an initialized instance of the Ticker.
// It works like NewTicker except that it has ability to close via context.
// Also it works fine with context.WithTimeout to handle max time to run ticker.
func NewTickerContext(ctx context.Context, min, max time.Duration) *Ticker {
ticker := &Ticker{
C: make(chan time.Time),
done: make(chan chan struct{}),
min: min.Nanoseconds(),
max: max.Nanoseconds(),
ctx: ctx,
}
go ticker.run()
return ticker
}
// NewTicker returns a pointer to an initialized instance of the Ticker.
// Min and max are durations of the shortest and longest allowed
// ticks. Ticker will run in a goroutine until explicitly stopped.
@@ -26,6 +45,7 @@ func NewTicker(min, max time.Duration) *Ticker {
done: make(chan chan struct{}),
min: min.Nanoseconds(),
max: max.Nanoseconds(),
ctx: context.Background(),
}
go ticker.run()
return ticker
@@ -33,9 +53,14 @@ func NewTicker(min, max time.Duration) *Ticker {
// Stop terminates the ticker goroutine and closes the C channel.
func (ticker *Ticker) Stop() {
if ticker.exit {
return
}
c := make(chan struct{})
ticker.done <- c
<-c
// close(ticker.C)
ticker.exit = true
}
func (ticker *Ticker) run() {
@@ -44,6 +69,8 @@ func (ticker *Ticker) run() {
for {
// either a stop signal or a timeout
select {
case <-ticker.ctx.Done():
t.Stop()
case c := <-ticker.done:
t.Stop()
close(c)