@@ -34,33 +34,39 @@ func (ft *fakeTicker) Stop() {
3434 ft .stop <- true
3535}
3636
37- // tick sends the tick time to the ticker channel after every period.
38- // Tick events are discarded if the underlying ticker channel does
39- // not have enough capacity.
40- func (ft * fakeTicker ) tick () {
41- tick := ft .clock .Now ()
42- for {
43- tick = tick .Add (ft .period )
44- remaining := tick .Sub (ft .clock .Now ())
45- if remaining <= 0 {
46- // The tick should have already happened. This can happen when
47- // Advance() is called on the fake clock with a duration larger
48- // than this ticker's period.
37+ // runTickThread initializes a background goroutine to send the tick time to the ticker channel
38+ // after every period. Tick events are discarded if the underlying ticker channel does not have
39+ // enough capacity.
40+ func (ft * fakeTicker ) runTickThread () {
41+ nextTick := ft .clock .Now ().Add (ft .period )
42+ next := ft .clock .After (ft .period )
43+ go func () {
44+ for {
4945 select {
50- case ft .c <- tick :
51- default :
46+ case <- ft .stop :
47+ return
48+ case <- next :
49+ // We send the time that the tick was supposed to occur at.
50+ tick := nextTick
51+ // Before sending the tick, we'll compute the next tick time and star the clock.After call.
52+ now := ft .clock .Now ()
53+ // First, figure out how many periods there have been between "now" and the time we were
54+ // supposed to have trigged, then advance over all of those.
55+ skipTicks := (now .Sub (tick ) + ft .period - 1 ) / ft .period
56+ nextTick = nextTick .Add (skipTicks * ft .period )
57+ // Now, keep advancing until we are past now. This should happen at most once.
58+ for ! nextTick .After (now ) {
59+ nextTick = nextTick .Add (ft .period )
60+ }
61+ // Figure out how long between now and the next scheduled tick, then wait that long.
62+ remaining := nextTick .Sub (now )
63+ next = ft .clock .After (remaining )
64+ // Finally, we can actually send the tick.
65+ select {
66+ case ft .c <- tick :
67+ default :
68+ }
5269 }
53- continue
5470 }
55-
56- select {
57- case <- ft .stop :
58- return
59- case <- ft .clock .After (remaining ):
60- select {
61- case ft .c <- tick :
62- default :
63- }
64- }
65- }
71+ }()
6672}
0 commit comments