rate_limiter

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2026 License: MIT Imports: 6 Imported by: 0

README

Rate limiting for implementation for rueidis package

Go Reference

This package is based on rwz/redis-gcra and implements GCRA (aka leaky bucket) and go-redis redis_rate for go code inspiration for rate limiting based on Redis. The code requires Redis version 3.2 or newer since it relies on replicate_commands feature.

Installation

redis_rate supports 2 last Go versions and requires a Go version with modules support. So make sure to initialize a Go module:

go mod init github.com/my/repo
go get github.com/jsjain/go-rate-limiter

Example

package main

import (
	"context"
	"fmt"

	rl "github.com/jsjain/go-rate-limiter"
)

func ExampleNewLimiter() {
	client, err := rueidis.NewClient(rueidis.ClientOption{
	InitAddress:           []string{"127.0.0.1:6379"},
  })
  if err != nil {
    panic(err)
  }
	limiter := rl.NewLimiter(client)
	res, err := limiter.Allow(ctx, "key")
	if err != nil {
		panic(err)
	}
	fmt.Println("allowed", res.Allowed, "remaining", res.Remaining)
	// Output: allowed 1 remaining 9
}
Setting custom rate limits for different keys and default rate limit
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/alphadose/haxmap"
	rl "github.com/jsjain/go-rate-limiter"
	"github.com/redis/rueidis"
)

func NewLimiterWithCustomLimits() {
	client, err := rueidis.NewClient(rueidis.ClientOption{
		InitAddress: []string{"127.0.0.1:6379"},
	})
	if err != nil {
		panic(err)
	}
	customLimits := haxmap.New[string, Limit]()
	customLimits.Set("key1", Limit{Burst: 50, Rate: 50, Period: time.Second})
	limiter := rl.NewLimiter(client, WithCustomLimits(customLimits), WithRateLimit(rl.PerSecond(20)))
	
	res, err := limiter.Allow(context.Background(), "key")
	if err != nil {
		panic(err)
	}
	fmt.Println("allowed", res.Allowed, "remaining", res.Remaining)
	// Output: allowed 1 remaining 19

	res, err := limiter.Allow(context.Background(), "key1")
	if err != nil {
		panic(err)
	}
	fmt.Println("allowed", res.Allowed, "remaining", res.Remaining)
	// Output: allowed 1 remaining 49
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Limit

type Limit struct {
	Rate   int
	Burst  int
	Period time.Duration
}

func PerDay

func PerDay(rate int) Limit

func PerHour

func PerHour(rate int) Limit

func PerMinute

func PerMinute(rate int) Limit

func PerSecond

func PerSecond(rate int) Limit

func (Limit) IsZero

func (l Limit) IsZero() bool

func (Limit) String

func (l Limit) String() string

type Limiter

type Limiter struct {
	// contains filtered or unexported fields
}

Limiter controls how frequently events are allowed to happen.

func NewLimiter

func NewLimiter(rdb rueidis.Client, opts ...LimiterOption) *Limiter

NewLimiter returns a new Limiter.

func (Limiter) Allow

func (l Limiter) Allow(ctx context.Context, key string) (*Result, error)

Allow is a shortcut for AllowN(ctx, key, limit, 1).

func (Limiter) AllowAtMost

func (l Limiter) AllowAtMost(
	ctx context.Context,
	key string,
	limit Limit,
	n int,
) (*Result, error)

AllowAtMost reports whether at most n events may happen at time now. It returns number of allowed events that is less than or equal to n.

func (Limiter) AllowN

func (l Limiter) AllowN(
	ctx context.Context,
	key string,
	n int,
) (*Result, error)

AllowN reports whether n events may happen at time now.

func (*Limiter) Reset

func (l *Limiter) Reset(ctx context.Context, key string) error

Reset gets a key and reset all limitations and previous usages

func (*Limiter) SetCustomLimit added in v1.2.0

func (l *Limiter) SetCustomLimit(key string, limit Limit)

SetCustomLimit adds or updates a per-key rate limit after construction.

type LimiterOption

type LimiterOption func(*Limiter)

func WithCustomLimits

func WithCustomLimits(limits map[string]Limit) LimiterOption

WithCustomLimits sets per-key rate limits. These are compiled once at construction time, so per-call strconv overhead is avoided.

func WithPrefix added in v1.1.0

func WithPrefix(prefix string) LimiterOption

func WithRateLimit added in v1.0.0

func WithRateLimit(limit Limit) LimiterOption

type Result

type Result struct {
	// Limit is the limit that was used to obtain this result.
	Limit Limit

	// Allowed is the number of events that may happen at time now.
	Allowed int

	// Remaining is the maximum number of requests that could be
	// permitted instantaneously for this key given the current
	// state. For example, if a rate limiter allows 10 requests per
	// second and has already received 6 requests for this key this
	// second, Remaining would be 4.
	Remaining int

	// RetryAfter is the time until the next request will be permitted.
	// It should be -1 unless the rate limit has been exceeded.
	RetryAfter time.Duration

	// ResetAfter is the time until the RateLimiter returns to its
	// initial state for a given key. For example, if a rate limiter
	// manages requests per second and received one request 200ms ago,
	// Reset would return 800ms. You can also think of this as the time
	// until Limit and Remaining will be equal.
	ResetAfter time.Duration
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL