master
go 55 lines 1.28 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package ticker
4
5 import "time"
6
7 type (
8 // Ticker holds a channel that delivers ticks of a clock at intervals.
9 // The ticks are aligned to interval boundaries.
10 Ticker struct {
11 C <-chan int
12 done chan struct{}
13 loops int
14 interval time.Duration
15 }
16 )
17
18 // New returns a new Ticker containing a channel that will send the time with a period specified by the duration argument.
19 // It adjusts the intervals or drops ticks to make up for slow receivers.
20 // The duration must be greater than zero; if not, New will panic. Stop the Ticker to release associated resources.
21 func New(interval time.Duration) *Ticker {
22 ticker := &Ticker{
23 interval: interval,
24 done: make(chan struct{}, 1),
25 }
26 ticker.start()
27 return ticker
28 }
29
30 func (t *Ticker) start() {
31 ch := make(chan int)
32 t.C = ch
33 go func() {
34 LOOP:
35 for {
36 now := time.Now()
37 nextRun := now.Truncate(t.interval).Add(t.interval)
38
39 time.Sleep(nextRun.Sub(now))
40 select {
41 case <-t.done:
42 close(ch)
43 break LOOP
44 case ch <- t.loops:
45 t.loops++
46 }
47 }
48 }()
49 }
50
51 // Stop turns off a Ticker. After Stop, no more ticks will be sent.
52 // Stop does not close the channel, to prevent a read from the channel succeeding incorrectly.
53 func (t *Ticker) Stop() {
54 t.done <- struct{}{}
55 }