func bytesPerSecController(bytesPerSecCh <-chan bytesPerSecMsg, bytesPerSecDisplayCh chan<- string) { bytesRecdForSecond := rb.MakeNew(INFO) durationForSecond := rb.MakeNew(INFO) lookbackSecs := 5 timeToRedraw := make(chan bool) go func(timeToRedraw chan bool) { for { time.Sleep(1000 * time.Millisecond) timeToRedraw <- true } }(timeToRedraw) for { select { case msg := <-bytesPerSecCh: bytesRecdForSecond.IncrementAtBy(msg.receivedOnSec, msg.bytes) durationForSecond.IncrementAtBy(msg.receivedOnSec, int64(msg.duration)) case <-timeToRedraw: windowDur := durationForSecond.SumPrevN(lookbackSecs) windowBytes := bytesRecdForSecond.SumPrevN(lookbackSecs) // divide-by-zero guard if windowDur == 0 { windowDur = 1 } bytesPerSecDisplayCh <- fmt.Sprintf("%10.2f", float64(windowBytes)/float64(windowDur)*1000) } } }
// This sends messages to both the barsToDrawCh and the durationDisplayCh-- // so should I rename this method? func barsController( reqMadeOnSecListenerCh <-chan interface{}, failsOnSecCh <-chan int, barsToDrawCh chan<- currentBars, reqSecDisplayCh chan<- string, ) { requestsForSecond := rb.MakeNew(INFO) // one column for each clock second failsForSecond := rb.MakeNew(INFO) // one column for each clock second secsSeen := 0 timeToRedraw := make(chan bool) go func(timeToRedraw chan bool) { for { time.Sleep(1000 * time.Millisecond) timeToRedraw <- true if secsSeen <= 60 { secsSeen++ } } }(timeToRedraw) for { select { case msg := <-reqMadeOnSecListenerCh: second := msg.(int) requestsForSecond.IncrementAt(second) case second := <-failsOnSecCh: failsForSecond.IncrementAt(second) case <-timeToRedraw: barsToDrawCh <- currentBars{ requestsForSecond.GetArray(), failsForSecond.GetArray(), requestsForSecond.GetMax(), } reqSecDisplayCh <- fmt.Sprintf("%d/%2.2d/%2.2d", requestsForSecond.GetPrevVal(), // won't be accurate for first five secs requestsForSecond.SumPrevN(5)/5, requestsForSecond.SumPrevN(secsSeen)/ int64(secsSeen), ) } } }
func durationWinController( durationCh <-chan int64, durationDisplayCh chan<- string, ) { totalDurForSecond := rb.MakeNew(INFO) // total durations for each clock second countForSecond := rb.MakeNew(INFO) // how many received per second lookbackSecs := 5 // secsSeen := 0 timeToRedraw := make(chan bool) go func(timeToRedraw chan bool) { for { time.Sleep(1000 * time.Millisecond) timeToRedraw <- true } }(timeToRedraw) for { select { case dur := <-durationCh: totalDurForSecond.ChangeHeadBy(dur) countForSecond.IncrementHead() case <-timeToRedraw: windowDur := totalDurForSecond.SumPrevN(lookbackSecs) windowCount := countForSecond.SumPrevN(lookbackSecs) if windowCount > 0 { avgDur := float64(windowDur) / float64(windowCount) durationDisplayCh <- fmt.Sprintf("%11.2f\n (avg last %d)", avgDur, lookbackSecs) } else { durationDisplayCh <- "0" } } } }