github.com/haraldrudell/parl@v0.4.176/counter/runner.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package counter
     7  
     8  import (
     9  	"sync"
    10  	"time"
    11  )
    12  
    13  // runner is a container executing rate-counters for a particular interval
    14  type runner struct {
    15  	lock  sync.RWMutex
    16  	tasks []RateRunnerTask // behind lock
    17  }
    18  
    19  // runner returns a container for rate-counters of a particular interval
    20  func NewRunner() (run *runner) {
    21  	return &runner{}
    22  }
    23  
    24  // Add adds an additional rate-counter to this container
    25  func (r *runner) Add(task RateRunnerTask) {
    26  	r.lock.Lock()
    27  	defer r.lock.Unlock()
    28  
    29  	r.tasks = append(r.tasks, task)
    30  }
    31  
    32  // Do is invoked by a timer with an intended at time
    33  func (r *runner) Do(at time.Time) {
    34  	at = time.Now() // obtain accurate time-stamp
    35  	for i := 0; ; i++ {
    36  		task := r.task(i)
    37  		if task == nil {
    38  			return
    39  		}
    40  		task.Do(at)
    41  	}
    42  }
    43  
    44  // task returns task n 0…, nil if no such task exists
    45  func (r *runner) task(i int) (task RateRunnerTask) {
    46  	r.lock.RLock()
    47  	defer r.lock.RUnlock()
    48  
    49  	if i < 0 || i >= len(r.tasks) {
    50  		return
    51  	}
    52  	task = r.tasks[i]
    53  	return
    54  }