github.com/haraldrudell/parl@v0.4.176/counter/runners.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 "github.com/haraldrudell/parl" 13 "github.com/haraldrudell/parl/perrors" 14 "github.com/haraldrudell/parl/ptime" 15 ) 16 17 // RateRunner is a container managing threads executing rate-counter tasks by their period 18 type RateRunner struct { 19 g0 parl.GoGen 20 21 lock sync.Mutex 22 subGo parl.SubGo 23 m map[time.Duration]*runner 24 } 25 26 // NewRateRunner returns a thread-container for running rate-counter averaging 27 func NewRateRunner(g0 parl.GoGen) (rr *RateRunner) { 28 return &RateRunner{ 29 g0: g0, 30 m: map[time.Duration]*runner{}, 31 } 32 } 33 34 // RateRunnerTask describes a rate counter 35 type RateRunnerTask interface { 36 Do(at time.Time) // Do executes averaging for an accurate timestamp 37 } 38 39 // AddTask adds a new rate-counter to the container 40 func (rr *RateRunner) AddTask(period time.Duration, task RateRunnerTask) { 41 rr.lock.Lock() 42 defer rr.lock.Unlock() 43 44 if runner, ok := rr.m[period]; ok { 45 runner.Add(task) 46 return 47 } 48 49 if rr.g0 == nil { 50 panic(perrors.NewPF("RateCounters instantiated with parl.Go nil")) 51 } else if rr.subGo == nil { 52 rr.subGo = rr.g0.SubGo() 53 } 54 55 runner := NewRunner() 56 runner.Add(task) 57 go ptime.OnTickerThread(runner.Do, period, time.Local, rr.subGo.Go()) 58 rr.m[period] = runner 59 }