Skip to content

Instantly share code, notes, and snippets.

@17twenty
Created June 14, 2017 08:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 17twenty/d226d76027ab42d087ad5b3002bb0c1a to your computer and use it in GitHub Desktop.
Save 17twenty/d226d76027ab42d087ad5b3002bb0c1a to your computer and use it in GitHub Desktop.
Demo of using golang.org x time rate RateLimiter
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))
}
@vitaly-zdanevich
Copy link

vitaly-zdanevich commented Mar 12, 2022

//io.CopyBuffer(dst, NewReader(src, limit), buf)

What this commented line mean? Alternative solution? Wrong solution?

@17twenty
Copy link
Author

Hey @vitaly-zdanevich , I ended up wrapping this up in my gorillimiter package. Thanks!

@vitaly-zdanevich
Copy link

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