ticker.go (1374B)
1 package clockwork 2 3 import ( 4 "time" 5 ) 6 7 // Ticker provides an interface which can be used instead of directly 8 // using the ticker within the time module. The real-time ticker t 9 // provides ticks through t.C which becomes now t.Chan() to make 10 // this channel requirement definable in this interface. 11 type Ticker interface { 12 Chan() <-chan time.Time 13 Stop() 14 } 15 16 type realTicker struct{ *time.Ticker } 17 18 func (rt *realTicker) Chan() <-chan time.Time { 19 return rt.C 20 } 21 22 type fakeTicker struct { 23 c chan time.Time 24 stop chan bool 25 clock FakeClock 26 period time.Duration 27 } 28 29 func (ft *fakeTicker) Chan() <-chan time.Time { 30 return ft.c 31 } 32 33 func (ft *fakeTicker) Stop() { 34 ft.stop <- true 35 } 36 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. 49 select { 50 case ft.c <- tick: 51 default: 52 } 53 continue 54 } 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 } 66 }