// Produce implements Producer. It creates a new value from the Generator every // interval, and sends it down the provided channel func (p *BaseProducer) Produce(kill <-chan struct{}) <-chan []Output { out := make(chan []Output) go func() { defer close(out) t := util.NewTicker(p.Interval, true) defer t.Kill() for { select { case <-t.C: data, err := p.Generate() if err != nil { fmt.Fprintf(os.Stderr, "Error generating output for %v: %v\n", p.Name, err) data = []Output{{ FullText: fmt.Sprintf("ERROR from %v: %v", p.Name, err), Color: DefaultColors.Crit, Separator: true, }} } // Attempt to send the output p.sendOutput(out, data, kill) case <-kill: return } } }() return out }
func (i *I3bar) loop() { defer close(i.json) t := util.NewTicker(i.interval, true) defer t.Kill() go output(i.json) for { select { case update := <-i.in: i.values[update.Key] = update.Out case event := <-i.clicks: producer, ok := i.producers[event.Name] if !ok { // Somebody didn't register with the right name, oh well continue } clicker, ok := producer.(Clicker) if !ok { // Producer doesn't support clicking, oh well continue } go clicker.Click(event) case <-t.C: items := i.collect() select { case <-i.kill: return case i.json <- items: continue } case <-i.kill: return } } }
// generateIO generates a map of interface name to average disk IO for the // past interval each interval, and sends it down the channel. Any errors are // sent down the error channel func generateIO(kill <-chan struct{}, interval time.Duration, devices ...string) (<-chan map[string]float64, chan error) { out := make(chan map[string]float64) errCh := make(chan error) go func() { tick := util.NewTicker(interval, true) defer tick.Kill() secs := interval.Seconds() // Keeps a record of our last checked IO count, so we can calculate our delta prev := make(map[string]uint64, len(devices)) for { select { case <-tick.C: send := make(map[string]float64, len(devices)) stats, err := currentIOStatus(devices...) if err != nil { errCh <- err continue } for _, d := range devices { // Retrieve the IO stats of this device usage, ok := stats[d] if !ok { errCh <- fmt.Errorf("No device found: %v", d) continue } // Retrieve previous value from cache pr, ok := prev[d] if !ok { // If unavailable send zero, then update cache prev[d] = usage send[d] = 0 continue } diff := float64(usage - pr) // Create average throughput by dividing by number of secs in interval val := diff / secs if diff == 0 { val = 0.0 } // Update map to send send[d] = val // Update cache prev[d] = usage } out <- send case <-kill: return } } }() return out, errCh }