Skip to content

Instantly share code, notes, and snippets.

@mhrlife
Created November 7, 2023 16:14
Show Gist options
  • Save mhrlife/27de310eb719b907b17c07151f8817a7 to your computer and use it in GitHub Desktop.
Save mhrlife/27de310eb719b907b17c07151f8817a7 to your computer and use it in GitHub Desktop.
//go:embed gcra.lua
var gcraScript string
type RateLimit struct {
rdb *redis.Client
prefix string
gcra *redis.Script
timeout time.Duration
}
func NewRateLimiter(rdb *redis.Client, prefix string, timeout time.Duration) *RateLimit {
gcra := redis.NewScript(gcraScript)
return &RateLimit{
rdb: rdb,
gcra: gcra,
prefix: prefix,
timeout: timeout,
}
}
func (r *RateLimit) Take(ctx context.Context, key string, burst int, interval float64) (bool, error) {
ctx, cancel := context.WithTimeout(ctx, r.timeout)
defer cancel()
values, err := r.gcra.Run(ctx, r.rdb, []string{r.key(key)}, burst, interval).Result()
if err != nil {
logrus.WithError(err).Error("error while executing GCRA script")
return false, err
}
return values.([]interface{})[0].(int64) == 1, nil
}
func (r *RateLimit) key(key string) string {
return fmt.Sprintf("%s:%s", r.prefix, key)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment