github.com/embeddedgo/x@v0.0.6-0.20191217015414-d79a36f562e7/time/tick.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package time 6 7 import "errors" 8 9 // A Ticker holds a channel that delivers `ticks' of a clock 10 // at intervals. 11 type Ticker struct { 12 C <-chan Time // The channel on which the ticks are delivered. 13 r runtimeTimer 14 } 15 16 // NewTicker returns a new Ticker containing a channel that will send the 17 // time with a period specified by the duration argument. 18 // It adjusts the intervals or drops ticks to make up for slow receivers. 19 // The duration d must be greater than zero; if not, NewTicker will panic. 20 // Stop the ticker to release associated resources. 21 func NewTicker(d Duration) *Ticker { 22 if d <= 0 { 23 panic(errors.New("non-positive interval for NewTicker")) 24 } 25 // Give the channel a 1-element time buffer. 26 // If the client falls behind while reading, we drop ticks 27 // on the floor until the client catches up. 28 c := make(chan Time, 1) 29 t := &Ticker{ 30 C: c, 31 r: runtimeTimer{ 32 when: when(d), 33 period: int64(d), 34 f: sendTime, 35 arg: c, 36 }, 37 } 38 startTimer(&t.r) 39 return t 40 } 41 42 // Stop turns off a ticker. After Stop, no more ticks will be sent. 43 // Stop does not close the channel, to prevent a concurrent goroutine 44 // reading from the channel from seeing an erroneous "tick". 45 func (t *Ticker) Stop() { 46 stopTimer(&t.r) 47 } 48 49 // Tick is a convenience wrapper for NewTicker providing access to the ticking 50 // channel only. While Tick is useful for clients that have no need to shut down 51 // the Ticker, be aware that without a way to shut it down the underlying 52 // Ticker cannot be recovered by the garbage collector; it "leaks". 53 // Unlike NewTicker, Tick will return nil if d <= 0. 54 func Tick(d Duration) <-chan Time { 55 if d <= 0 { 56 return nil 57 } 58 return NewTicker(d).C 59 }