blob: aa56952e711cf1e7360dec0585909dce85898c62 [file] [log] [blame]
khenaidoo26721882021-08-11 17:42:52 -04001package clockwork
2
Abhay Kumar40252eb2025-10-13 13:25:53 +00003import "time"
khenaidoo26721882021-08-11 17:42:52 -04004
Abhay Kumar40252eb2025-10-13 13:25:53 +00005// Ticker provides an interface which can be used instead of directly using
6// [time.Ticker]. The real-time ticker t provides ticks through t.C which
7// becomes t.Chan() to make this channel requirement definable in this
8// interface.
khenaidoo26721882021-08-11 17:42:52 -04009type Ticker interface {
10 Chan() <-chan time.Time
Abhay Kumar40252eb2025-10-13 13:25:53 +000011 Reset(d time.Duration)
khenaidoo26721882021-08-11 17:42:52 -040012 Stop()
13}
14
15type realTicker struct{ *time.Ticker }
16
Abhay Kumar40252eb2025-10-13 13:25:53 +000017func (r realTicker) Chan() <-chan time.Time {
18 return r.C
khenaidoo26721882021-08-11 17:42:52 -040019}
20
21type fakeTicker struct {
Abhay Kumar40252eb2025-10-13 13:25:53 +000022 // The channel associated with the firer, used to send expiration times.
23 c chan time.Time
24
25 // The time when the ticker expires. Only meaningful if the ticker is currently
26 // one of a FakeClock's waiters.
27 exp time.Time
28
29 // reset and stop provide the implementation of the respective exported
30 // functions.
31 reset func(d time.Duration)
32 stop func()
33
34 // The duration of the ticker.
35 d time.Duration
khenaidoo26721882021-08-11 17:42:52 -040036}
37
Abhay Kumar40252eb2025-10-13 13:25:53 +000038func newFakeTicker(fc *FakeClock, d time.Duration) *fakeTicker {
39 var ft *fakeTicker
40 ft = &fakeTicker{
41 c: make(chan time.Time, 1),
42 d: d,
43 reset: func(d time.Duration) {
44 fc.l.Lock()
45 defer fc.l.Unlock()
46 ft.d = d
47 fc.setExpirer(ft, d)
48 },
49 stop: func() { fc.stop(ft) },
50 }
51 return ft
khenaidoo26721882021-08-11 17:42:52 -040052}
53
Abhay Kumar40252eb2025-10-13 13:25:53 +000054func (f *fakeTicker) Chan() <-chan time.Time { return f.c }
55
56func (f *fakeTicker) Reset(d time.Duration) { f.reset(d) }
57
58func (f *fakeTicker) Stop() { f.stop() }
59
60func (f *fakeTicker) expire(now time.Time) *time.Duration {
61 // Never block on expiration.
62 select {
63 case f.c <- now:
64 default:
65 }
66 return &f.d
khenaidoo26721882021-08-11 17:42:52 -040067}
68
Abhay Kumar40252eb2025-10-13 13:25:53 +000069func (f *fakeTicker) expiration() time.Time { return f.exp }
70
71func (f *fakeTicker) setExpiration(t time.Time) { f.exp = t }