mirror of
https://github.com/hanzozt/transport.git
synced 2026-10-30 14:46:37 +00:00
48 lines
944 B
Go
48 lines
944 B
Go
package shaper
|
|
|
|
import (
|
|
"io"
|
|
"time"
|
|
)
|
|
|
|
func LimitWriter(w io.Writer, span time.Duration, maxRatePerSpan int64) io.Writer {
|
|
return &Shaper{
|
|
wrapped: w,
|
|
limit: maxRatePerSpan,
|
|
span: span,
|
|
}
|
|
}
|
|
|
|
type Shaper struct {
|
|
wrapped io.Writer
|
|
interval time.Time
|
|
span time.Duration
|
|
written int64
|
|
limit int64
|
|
}
|
|
|
|
func (self *Shaper) Write(p []byte) (n int, err error) {
|
|
inNextInterval := false
|
|
if self.written >= self.limit {
|
|
current := time.Now().Truncate(self.span)
|
|
for current.Equal(self.interval) {
|
|
current = time.Now().Truncate(self.span)
|
|
// busy wait until we're in the next interval
|
|
}
|
|
self.interval = current
|
|
inNextInterval = true
|
|
}
|
|
|
|
n, err = self.wrapped.Write(p)
|
|
if inNextInterval {
|
|
self.written = int64(n)
|
|
} else if current := time.Now().Truncate(self.span); current != self.interval {
|
|
self.written = int64(n)
|
|
self.interval = current
|
|
} else {
|
|
self.written += int64(n)
|
|
}
|
|
|
|
return n, err
|
|
}
|