2014-03-02 23:03:00 -08:00
|
|
|
// Package bandwidth is a simple tool for keeping track of transmitted and
|
|
|
|
// received counts (ostensibly bytes).
|
2014-03-02 22:47:28 -08:00
|
|
|
package bandwidth
|
2014-03-02 22:44:09 -08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2014-03-08 00:45:55 -08:00
|
|
|
"log"
|
|
|
|
"sort"
|
2014-03-02 22:44:09 -08:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2014-03-02 23:03:00 -08:00
|
|
|
// Bandwidth keeps track of state for Rx and Tx (byte) counts. Instantiate
|
|
|
|
// a Bandwidth then feed values using the AddRx and AddTx channels. When the
|
|
|
|
// accumulated values are needed, simply read from the Rx or Tx chans. When the
|
|
|
|
// Bandwidth is no loner needed close the Quit chan.
|
|
|
|
type Bandwidth struct {
|
|
|
|
// write number of bytes to us
|
|
|
|
AddRx chan int
|
|
|
|
AddTx chan int
|
|
|
|
|
|
|
|
// read stats from us
|
|
|
|
Rx chan []float64
|
|
|
|
Tx chan []float64
|
|
|
|
|
|
|
|
Quit chan interface{}
|
|
|
|
|
2014-03-08 00:45:55 -08:00
|
|
|
rxSnap []float64
|
|
|
|
txSnap []float64
|
|
|
|
dt time.Duration
|
|
|
|
|
|
|
|
curRx int
|
|
|
|
curTx int
|
|
|
|
|
|
|
|
rxstream []int
|
|
|
|
txstream []int
|
|
|
|
|
|
|
|
timeI int
|
|
|
|
max int
|
2014-03-02 23:03:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewBandwidth Returns a populated and ready to launch Bandwidth. seconds is
|
|
|
|
// a slice of seconds on which to report (e.g. 1, 10, 60 seconds). dt is how
|
|
|
|
// often the values used to send to Rx and Tx are updated.
|
2014-03-08 00:45:55 -08:00
|
|
|
func NewBandwidth(dts []int, dt time.Duration) (*Bandwidth, error) {
|
|
|
|
if len(dts) < 1 {
|
2014-03-02 23:03:00 -08:00
|
|
|
return nil, errors.New("must specify at least one interval lenght")
|
|
|
|
}
|
2014-03-08 00:45:55 -08:00
|
|
|
sort.Ints(dts)
|
|
|
|
max := dts[len(dts)-1]
|
2014-03-02 23:03:00 -08:00
|
|
|
r := &Bandwidth{
|
|
|
|
AddRx: make(chan int, 1024),
|
|
|
|
AddTx: make(chan int, 1024),
|
|
|
|
Rx: make(chan []float64),
|
|
|
|
Tx: make(chan []float64),
|
|
|
|
dt: dt,
|
|
|
|
Quit: make(chan interface{}),
|
2014-03-08 00:45:55 -08:00
|
|
|
rxstream: make([]int, max),
|
|
|
|
txstream: make([]int, max),
|
|
|
|
max: max,
|
2014-03-02 23:03:00 -08:00
|
|
|
}
|
|
|
|
return r, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run is a method of Bandwidth that must be started in a goroutine in order
|
|
|
|
// for things to be functional.
|
|
|
|
func (bw *Bandwidth) Run() {
|
|
|
|
t := time.NewTicker(bw.dt)
|
|
|
|
outer:
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-t.C:
|
2014-03-08 00:45:55 -08:00
|
|
|
bw.rxSnap = bw.averages(bw.rxstream)
|
|
|
|
bw.txSnap = bw.averages(bw.txstream)
|
|
|
|
bw.curTx = 0
|
|
|
|
bw.curRx = 0
|
|
|
|
bw.timeI += 1
|
2014-03-02 23:03:00 -08:00
|
|
|
case bw.Rx <- bw.rxSnap:
|
|
|
|
case bw.Tx <- bw.txSnap:
|
|
|
|
case s := <-bw.AddRx:
|
2014-03-08 00:45:55 -08:00
|
|
|
bw.curTx += s
|
2014-03-02 23:03:00 -08:00
|
|
|
case s := <-bw.AddTx:
|
2014-03-08 00:45:55 -08:00
|
|
|
bw.curRx += s
|
2014-03-02 23:03:00 -08:00
|
|
|
case <-bw.Quit:
|
|
|
|
break outer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(bw.AddRx)
|
|
|
|
close(bw.AddTx)
|
2014-03-03 22:59:50 -08:00
|
|
|
close(bw.Rx)
|
|
|
|
close(bw.Tx)
|
2014-03-02 23:03:00 -08:00
|
|
|
}
|
|
|
|
|
2014-03-08 00:45:55 -08:00
|
|
|
func (bw *Bandwidth) averages(state []int) []float64 {
|
|
|
|
for i := 0; i < bw.max; i++ {
|
|
|
|
log.Println(bw.timeI + i)
|
2014-03-03 22:59:50 -08:00
|
|
|
}
|
2014-03-08 00:45:55 -08:00
|
|
|
return nil
|
2014-03-02 22:44:09 -08:00
|
|
|
}
|