github.com/cavaliergopher/grab/v3@v3.0.1/pkg/bps/bps.go (about) 1 /* 2 Package bps provides gauges for calculating the Bytes Per Second transfer rate 3 of data streams. 4 */ 5 package bps 6 7 import ( 8 "context" 9 "time" 10 ) 11 12 // Gauge is the common interface for all BPS gauges in this package. Given a 13 // set of samples over time, each gauge type can be used to measure the Bytes 14 // Per Second transfer rate of a data stream. 15 // 16 // All samples must monotonically increase in timestamp and value. Each sample 17 // should represent the total number of bytes sent in a stream, rather than 18 // accounting for the number sent since the last sample. 19 // 20 // To ensure a gauge can report progress as quickly as possible, take an initial 21 // sample when your stream first starts. 22 // 23 // All gauge implementations are safe for concurrent use. 24 type Gauge interface { 25 // Sample adds a new sample of the progress of the monitored stream. 26 Sample(t time.Time, n int64) 27 28 // BPS returns the calculated Bytes Per Second rate of the monitored stream. 29 BPS() float64 30 } 31 32 // SampleFunc is used by Watch to take periodic samples of a monitored stream. 33 type SampleFunc func() (n int64) 34 35 // Watch will periodically call the given SampleFunc to sample the progress of 36 // a monitored stream and update the given gauge. SampleFunc should return the 37 // total number of bytes transferred by the stream since it started. 38 // 39 // Watch is a blocking call and should typically be called in a new goroutine. 40 // To prevent the goroutine from leaking, make sure to cancel the given context 41 // once the stream is completed or canceled. 42 func Watch(ctx context.Context, g Gauge, f SampleFunc, interval time.Duration) { 43 g.Sample(time.Now(), f()) 44 t := time.NewTicker(interval) 45 defer t.Stop() 46 for { 47 select { 48 case <-ctx.Done(): 49 return 50 case now := <-t.C: 51 g.Sample(now, f()) 52 } 53 } 54 }