Created
June 14, 2017 08:39
-
-
Save 17twenty/d226d76027ab42d087ad5b3002bb0c1a to your computer and use it in GitHub Desktop.
Demo of using golang.org x time rate RateLimiter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"fmt" | |
"io" | |
"time" | |
"golang.org/x/time/rate" | |
) | |
type reader struct { | |
r io.Reader | |
limiter *rate.Limiter | |
} | |
// NewReader returns a reader that is rate limited by | |
// the given token bucket. Each token in the bucket | |
// represents one byte. | |
func NewReader(r io.Reader, l *rate.Limiter) io.Reader { | |
return &reader{ | |
r: r, | |
limiter: l, | |
} | |
} | |
func (r *reader) Read(buf []byte) (int, error) { | |
n, err := r.r.Read(buf) | |
if n <= 0 { | |
return n, err | |
} | |
now := time.Now() | |
rv := r.limiter.ReserveN(now, n) | |
if !rv.OK() { | |
return 0, fmt.Errorf("Exceeds limiter's burst") | |
} | |
delay := rv.DelayFrom(now) | |
//fmt.Printf("Read %d bytes, delay %d\n", n, delay) | |
time.Sleep(delay) | |
return n, err | |
} | |
func main() { | |
// Source holding 1MB | |
src := bytes.NewReader(make([]byte, 1024*1024)) | |
// Destination | |
dst := &bytes.Buffer{} | |
// Bucket adding 100KB every second, holding max 100KB | |
limit := rate.NewLimiter(100*1024, 100*1024) | |
start := time.Now() | |
buf := make([]byte, 10*1024) | |
// Copy source to destination, but wrap our reader with rate limited one | |
//io.CopyBuffer(dst, NewReader(src, limit), buf) | |
r := NewReader(src, limit) | |
for { | |
if n, err := r.Read(buf); err == nil { | |
dst.Write(buf[0:n]) | |
} else { | |
break | |
} | |
} | |
fmt.Printf("Copied %d bytes in %s\n", dst.Len(), time.Since(start)) | |
} |
Hey @vitaly-zdanevich , I ended up wrapping this up in my gorillimiter package. Thanks!
buf := make([]byte, 10*1024)
This variable and its usage looks like wasting of RAM.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
//io.CopyBuffer(dst, NewReader(src, limit), buf)
What this commented line mean? Alternative solution? Wrong solution?