From 9c8b64eaf3d7cb19426b0557b8989400b0ecc21f Mon Sep 17 00:00:00 2001 From: fantasticbin Date: Wed, 20 Nov 2024 14:35:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AB=8B=E5=8D=B3=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E5=AE=9A=E6=97=B6=E5=99=A8=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ticker/ticker.go | 43 ++++++++++++++++++++++++++++++++++++++ ticker/ticker_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 ticker/ticker.go create mode 100644 ticker/ticker_test.go diff --git a/ticker/ticker.go b/ticker/ticker.go new file mode 100644 index 0000000..2bd9197 --- /dev/null +++ b/ticker/ticker.go @@ -0,0 +1,43 @@ +package ticker + +import "time" + +type Ticker struct { + C chan time.Time + ticker *time.Ticker + close chan struct{} +} + +func NewTicker(d time.Duration) *Ticker { + return &Ticker{ + C: make(chan time.Time, 1), + ticker: time.NewTicker(d), + close: make(chan struct{}), + } +} + +func (t *Ticker) Start() { + // 首次直接触发 + t.C <- time.Now() + go func() { + for { + select { + case <-t.close: + // 关闭时停止goroutine + return + case tc := <-t.ticker.C: + // 把go原生定时器 push 的时间推送到我们定义的 time channel 中 + t.C <- tc + } + } + }() +} + +func (t *Ticker) Reset(d time.Duration) { + t.ticker.Reset(d) +} + +func (t *Ticker) Stop() { + t.ticker.Stop() + close(t.close) +} diff --git a/ticker/ticker_test.go b/ticker/ticker_test.go new file mode 100644 index 0000000..7750a80 --- /dev/null +++ b/ticker/ticker_test.go @@ -0,0 +1,48 @@ +package ticker + +import ( + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestTicker(t *testing.T) { + now := time.Now() + // 记录初始时间 + data := []int64{ + now.Unix(), + } + expected := []int64{ + now.Unix(), + } + + // 预期每隔一秒收到一个信号 + for i := 0; i < 3; i++ { + expected = append(expected, now.Add(time.Duration(i)*time.Second).Unix()) + } + + done := make(chan struct{}) + ticker := NewTicker(time.Second) + ticker.Start() + + go func() { + for { + select { + case <-done: + return + case t := <-ticker.C: + data = append(data, t.Unix()) + } + } + }() + + go func() { + // 设置成3秒有时候会有误差 + time.Sleep(2500 * time.Millisecond) + ticker.Stop() + close(done) + }() + + time.Sleep(3 * time.Second) + assert.Equal(t, expected, data) +}