55 lines
1.7 KiB
Go
55 lines
1.7 KiB
Go
/*
|
|
Package bps provides gauges for calculating the Bytes Per Second transfer rate
|
|
of data streams.
|
|
*/
|
|
package bps
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// Gauge is the common interface for all BPS gauges in this package. Given a
|
|
// set of samples over time, each gauge type can be used to measure the Bytes
|
|
// Per Second transfer rate of a data stream.
|
|
//
|
|
// All samples must monotonically increase in timestamp and value. Each sample
|
|
// should represent the total number of bytes sent in a stream, rather than
|
|
// accounting for the number sent since the last sample.
|
|
//
|
|
// To ensure a gauge can report progress as quickly as possible, take an initial
|
|
// sample when your stream first starts.
|
|
//
|
|
// All gauge implementations are safe for concurrent use.
|
|
type Gauge interface {
|
|
// Sample adds a new sample of the progress of the monitored stream.
|
|
Sample(t time.Time, n int64)
|
|
|
|
// BPS returns the calculated Bytes Per Second rate of the monitored stream.
|
|
BPS() float64
|
|
}
|
|
|
|
// SampleFunc is used by Watch to take periodic samples of a monitored stream.
|
|
type SampleFunc func() (n int64)
|
|
|
|
// Watch will periodically call the given SampleFunc to sample the progress of
|
|
// a monitored stream and update the given gauge. SampleFunc should return the
|
|
// total number of bytes transferred by the stream since it started.
|
|
//
|
|
// Watch is a blocking call and should typically be called in a new goroutine.
|
|
// To prevent the goroutine from leaking, make sure to cancel the given context
|
|
// once the stream is completed or canceled.
|
|
func Watch(ctx context.Context, g Gauge, f SampleFunc, interval time.Duration) {
|
|
g.Sample(time.Now(), f())
|
|
t := time.NewTicker(interval)
|
|
defer t.Stop()
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case now := <-t.C:
|
|
g.Sample(now, f())
|
|
}
|
|
}
|
|
}
|