github.com/netdata/go.d.plugin@v0.58.1/agent/ticker/ticker.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package ticker
     4  
     5  import "time"
     6  
     7  type (
     8  	// Ticker holds a channel that delivers ticks of a clock at intervals.
     9  	// The ticks are aligned to interval boundaries.
    10  	Ticker struct {
    11  		C        <-chan int
    12  		done     chan struct{}
    13  		loops    int
    14  		interval time.Duration
    15  	}
    16  )
    17  
    18  // New returns a new Ticker containing a channel that will send the time with a period specified by the duration argument.
    19  // It adjusts the intervals or drops ticks to make up for slow receivers.
    20  // The duration must be greater than zero; if not, New will panic. Stop the Ticker to release associated resources.
    21  func New(interval time.Duration) *Ticker {
    22  	ticker := &Ticker{
    23  		interval: interval,
    24  		done:     make(chan struct{}, 1),
    25  	}
    26  	ticker.start()
    27  	return ticker
    28  }
    29  
    30  func (t *Ticker) start() {
    31  	ch := make(chan int)
    32  	t.C = ch
    33  	go func() {
    34  	LOOP:
    35  		for {
    36  			now := time.Now()
    37  			nextRun := now.Truncate(t.interval).Add(t.interval)
    38  
    39  			time.Sleep(nextRun.Sub(now))
    40  			select {
    41  			case <-t.done:
    42  				close(ch)
    43  				break LOOP
    44  			case ch <- t.loops:
    45  				t.loops++
    46  			}
    47  		}
    48  	}()
    49  }
    50  
    51  // Stop turns off a Ticker. After Stop, no more ticks will be sent.
    52  // Stop does not close the channel, to prevent a read from the channel succeeding incorrectly.
    53  func (t *Ticker) Stop() {
    54  	t.done <- struct{}{}
    55  }