Example #1
0
// 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
}
Example #2
0
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
		}
	}
}
Example #3
0
// 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
}