func (m *diskInfo) update(read, write uint64) (readRate, writeRate int) {
	duration := timing.Now().Sub(m.updateTime).Seconds()
	if read != m.lastRead {
		readRate = int(float64(read-m.lastRead) / duration)
	}
	if write != m.lastWrite {
		writeRate = int(float64(write-m.lastWrite) / duration)
	}
	m.lastRead = read
	m.lastWrite = write
	m.updateTime = timing.Now()
	return  
}
update updates the last read information, and returns
the delta read and written since the last update in bytes/sec.
package diskio  
import (
	"bufio"
	"strconv"
	"strings"
	"sync"
	"time"
	"barista.run/bar"
	"barista.run/base/value"
	"barista.run/format"
	l "barista.run/logging"
	"barista.run/outputs"
	"barista.run/timing"
	"github.com/martinlindhe/unit"
	"github.com/spf13/afero"
)
type IO struct {
	Input, Output unit.Datarate
	shouldOutput bool
	err          error
}
func (i IO) Total() unit.Datarate {
	return i.Input + i.Output
}
type diskInfo struct {
	ioChan     chan<- IO
	lastIO     *IO
	lastRead   uint64
	lastWrite  uint64
	updateTime time.Time
}
var once sync.Once
var lock sync.Mutex
var modules map[string]*diskInfo
var updater *timing.Scheduler
func construct() {
	once.Do(func() {
		modules = make(map[string]*diskInfo)
		updater = timing.NewScheduler()
		l.Attach(nil, updater, "diskio.updater")
		updater.Every(3 * time.Second)
		update()
		go func(updater *timing.Scheduler) {
			for range updater.C {
				update()
			}
		}(updater)
	})
}
func RefreshInterval(interval time.Duration) {
	construct()
	updater.Every(interval)
}
type Module struct {
	ioChan     <-chan IO
	outputFunc value.Value
}
func New(disk string) *Module {
	construct()
	lock.Lock()
	defer lock.Unlock()
	mInfo, found := modules[disk]
	if !found {
		mInfo = &diskInfo{}
		modules[disk] = mInfo
	}
	m := &Module{ioChan: mInfo.makeChannel()}
	l.Label(m, disk)
	l.Register(m, "ioChan", "outputFunc")
	m.Output(func(i IO) bar.Output {
		return outputs.Textf("Disk: %s", format.IByterate(i.Total()))
	})
	return m
}
func (m *Module) Output(outputFunc func(IO) bar.Output) *Module {
	m.outputFunc.Set(outputFunc)
	return m
}
func (m *Module) Stream(s bar.Sink) {
	var i IO
	outputFunc := m.outputFunc.Get().(func(IO) bar.Output)
	nextOutputFunc, done := m.outputFunc.Subscribe()
	defer done()
	for {
		select {
		case i = <-m.ioChan:
		case <-nextOutputFunc:
			outputFunc = m.outputFunc.Get().(func(IO) bar.Output)
		}
		if s.Error(i.err) {
			continue
		}
		if i.shouldOutput {
			s.Output(outputFunc(i))
		} else {
			s.Output(nil)
		}
	}
}