Skip to content

Commit 6d8d032

Browse files
authored
Remove firer struct & fix ticker reset (#95)
Remove firer interface & fixt ticker reset It also fixes an issue where ticker resets were not storing the new ticker duration. This would manifest as a ticker whose time was reset, but only for 1 tick, after which it would revert to the original time.
1 parent 91d2c0a commit 6d8d032

File tree

3 files changed

+52
-60
lines changed

3 files changed

+52
-60
lines changed

clockwork.go

+8-46
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ type expirer interface {
109109
expire(now time.Time) (next *time.Duration)
110110

111111
// Get and set the expiration time.
112-
expiry() time.Time
113-
setExpiry(time.Time)
112+
expiration() time.Time
113+
setExpiration(time.Time)
114114
}
115115

116116
// After mimics [time.After]; it waits for the given duration to elapse on the
@@ -153,17 +153,7 @@ func (fc *FakeClock) NewTicker(d time.Duration) Ticker {
153153
if d <= 0 {
154154
panic(errors.New("non-positive interval for NewTicker"))
155155
}
156-
var ft *fakeTicker
157-
ft = &fakeTicker{
158-
firer: newFirer(),
159-
d: d,
160-
reset: func(d time.Duration) {
161-
fc.l.Lock()
162-
defer fc.l.Unlock()
163-
fc.setExpirer(ft, d)
164-
},
165-
stop: func() { fc.stop(ft) },
166-
}
156+
ft := newFakeTicker(fc, d)
167157
fc.l.Lock()
168158
defer fc.l.Unlock()
169159
fc.setExpirer(ft, d)
@@ -192,7 +182,7 @@ func (fc *FakeClock) newTimer(d time.Duration, afterfunc func()) (*fakeTimer, ti
192182
fc.l.Lock()
193183
defer fc.l.Unlock()
194184
fc.setExpirer(ft, d)
195-
return ft, ft.expiry()
185+
return ft, ft.expiration()
196186
}
197187

198188
// newTimerAtTime is like newTimer, but uses a time instead of a duration.
@@ -218,12 +208,12 @@ func (fc *FakeClock) Advance(d time.Duration) {
218208
//
219209
// We don't iterate because the callback of the waiter might register a new
220210
// waiter, so the list of waiters might change as we execute this.
221-
for len(fc.waiters) > 0 && !end.Before(fc.waiters[0].expiry()) {
211+
for len(fc.waiters) > 0 && !end.Before(fc.waiters[0].expiration()) {
222212
w := fc.waiters[0]
223213
fc.waiters = fc.waiters[1:]
224214

225215
// Use the waiter's expiration as the current time for this expiration.
226-
now := w.expiry()
216+
now := w.expiration()
227217
fc.time = now
228218
if d := w.expire(now); d != nil {
229219
// Set the new expiration if needed.
@@ -311,10 +301,10 @@ func (fc *FakeClock) setExpirer(e expirer, d time.Duration) {
311301
return
312302
}
313303
// Add the expirer to the set of waiters and notify any blockers.
314-
e.setExpiry(fc.time.Add(d))
304+
e.setExpiration(fc.time.Add(d))
315305
fc.waiters = append(fc.waiters, e)
316306
slices.SortFunc(fc.waiters, func(a, b expirer) int {
317-
return a.expiry().Compare(b.expiry())
307+
return a.expiration().Compare(b.expiration())
318308
})
319309

320310
// Notify blockers of our new waiter.
@@ -327,31 +317,3 @@ func (fc *FakeClock) setExpirer(e expirer, d time.Duration) {
327317
return false
328318
})
329319
}
330-
331-
// firer is used by fakeTimer and fakeTicker used to help implement expirer.
332-
type firer struct {
333-
// The channel associated with the firer, used to send expiration times.
334-
c chan time.Time
335-
336-
// The time when the firer expires. Only meaningful if the firer is currently
337-
// one of a fakeClock's waiters.
338-
exp time.Time
339-
}
340-
341-
func newFirer() firer {
342-
return firer{c: make(chan time.Time, 1)}
343-
}
344-
345-
func (f *firer) Chan() <-chan time.Time {
346-
return f.c
347-
}
348-
349-
// expiry implements expirer.
350-
func (f *firer) expiry() time.Time {
351-
return f.exp
352-
}
353-
354-
// setExpiry implements expirer.
355-
func (f *firer) setExpiry(t time.Time) {
356-
f.exp = t
357-
}

ticker.go

+29-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ func (r realTicker) Chan() <-chan time.Time {
1919
}
2020

2121
type fakeTicker struct {
22-
firer
22+
// 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
2328

2429
// reset and stop provide the implementation of the respective exported
2530
// functions.
@@ -30,13 +35,27 @@ type fakeTicker struct {
3035
d time.Duration
3136
}
3237

33-
func (f *fakeTicker) Reset(d time.Duration) {
34-
f.reset(d)
38+
func 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
3552
}
3653

37-
func (f *fakeTicker) Stop() {
38-
f.stop()
39-
}
54+
func (f *fakeTicker) Chan() <-chan time.Time { return f.c }
55+
56+
func (f *fakeTicker) Reset(d time.Duration) { f.reset(d) }
57+
58+
func (f *fakeTicker) Stop() { f.stop() }
4059

4160
func (f *fakeTicker) expire(now time.Time) *time.Duration {
4261
// Never block on expiration.
@@ -46,3 +65,7 @@ func (f *fakeTicker) expire(now time.Time) *time.Duration {
4665
}
4766
return &f.d
4867
}
68+
69+
func (f *fakeTicker) expiration() time.Time { return f.exp }
70+
71+
func (f *fakeTicker) setExpiration(t time.Time) { f.exp = t }

timer.go

+15-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ func (r realTimer) Chan() <-chan time.Time {
1818
}
1919

2020
type fakeTimer struct {
21-
firer
21+
// The channel associated with the firer, used to send expiration times.
22+
c chan time.Time
23+
24+
// The time when the firer expires. Only meaningful if the firer is currently
25+
// one of a FakeClock's waiters.
26+
exp time.Time
2227

2328
// reset and stop provide the implementation of the respective exported
2429
// functions.
@@ -33,7 +38,7 @@ type fakeTimer struct {
3338
func newFakeTimer(fc *FakeClock, afterfunc func()) *fakeTimer {
3439
var ft *fakeTimer
3540
ft = &fakeTimer{
36-
firer: newFirer(),
41+
c: make(chan time.Time, 1),
3742
reset: func(d time.Duration) bool {
3843
fc.l.Lock()
3944
defer fc.l.Unlock()
@@ -49,13 +54,11 @@ func newFakeTimer(fc *FakeClock, afterfunc func()) *fakeTimer {
4954
return ft
5055
}
5156

52-
func (f *fakeTimer) Reset(d time.Duration) bool {
53-
return f.reset(d)
54-
}
57+
func (f *fakeTimer) Chan() <-chan time.Time { return f.c }
5558

56-
func (f *fakeTimer) Stop() bool {
57-
return f.stop()
58-
}
59+
func (f *fakeTimer) Reset(d time.Duration) bool { return f.reset(d) }
60+
61+
func (f *fakeTimer) Stop() bool { return f.stop() }
5962

6063
func (f *fakeTimer) expire(now time.Time) *time.Duration {
6164
if f.afterFunc != nil {
@@ -70,3 +73,7 @@ func (f *fakeTimer) expire(now time.Time) *time.Duration {
7073
}
7174
return nil
7275
}
76+
77+
func (f *fakeTimer) expiration() time.Time { return f.exp }
78+
79+
func (f *fakeTimer) setExpiration(t time.Time) { f.exp = t }

0 commit comments

Comments
 (0)