type Monitor … // New creates a new flow control monitor. Instantaneous transfer rate is // measured and updated for each sampleRate interval. windowSize determines the // weight of each sample in the exponential moving average (EMA) calculation. // The exact formulas are: // // sampleTime = currentTime - prevSampleTime // sampleRate = byteCount / sampleTime // weight = 1 - exp(-sampleTime/windowSize) // newRate = weight*sampleRate + (1-weight)*oldRate // // The default values for sampleRate and windowSize (if <= 0) are 100ms and 1s, // respectively. func New(sampleRate, windowSize time.Duration) *Monitor { … } // Update records the transfer of n bytes and returns n. It should be called // after each Read/Write operation, even if n is 0. func (m *Monitor) Update(n int) int { … } // IO is a convenience method intended to wrap io.Reader and io.Writer method // execution. It calls m.Update(n) and then returns (n, err) unmodified. func (m *Monitor) IO(n int, err error) (int, error) { … } // Done marks the transfer as finished and prevents any further updates or // limiting. Instantaneous and current transfer rates drop to 0. Update, IO, and // Limit methods become NOOPs. It returns the total number of bytes transferred. func (m *Monitor) Done() int64 { … } const timeRemLimit … type Status … // Status returns current transfer status information. The returned value // becomes static after a call to Done. func (m *Monitor) Status() Status { … } // Limit restricts the instantaneous (per-sample) data flow to rate bytes per // second. It returns the maximum number of bytes (0 <= n <= want) that may be // transferred immediately without exceeding the limit. If block == true, the // call blocks until n > 0. want is returned unmodified if want < 1, rate < 1, // or the transfer is inactive (after a call to Done). // // At least one byte is always allowed to be transferred in any given sampling // period. Thus, if the sampling rate is 100ms, the lowest achievable flow rate // is 10 bytes per second. // // For usage examples, see the implementation of Reader and Writer in io.go. func (m *Monitor) Limit(want int, rate int64, block bool) (n int) { … } // SetTransferSize specifies the total size of the data transfer, which allows // the Monitor to calculate the overall progress and time to completion. func (m *Monitor) SetTransferSize(bytes int64) { … } // update accumulates the transferred byte count for the current sample until // clock() - m.sLast >= m.sRate. The monitor status is updated once the current // sample is done. func (m *Monitor) update(n int) (now time.Duration) { … } // reset clears the current sample state in preparation for the next sample. func (m *Monitor) reset(sampleTime time.Duration) { … } // waitNextSample sleeps for the remainder of the current sample. The lock is // released and reacquired during the actual sleep period, so it's possible for // the transfer to be inactive when this method returns. func (m *Monitor) waitNextSample(now time.Duration) time.Duration { … }