Skip to content

Period Limiter

The limit.PeriodLimit is mainly used to limit requests within a period. It is implemented based on Redis and performs rate limiting operations through Lua scripts.

const (
// Unknown means not initialized state.
Unknown = iota
// Allowed means allowed state.
Allowed
// HitQuota means this request exactly hit the quota.
HitQuota
// OverQuota means passed the quota.
OverQuota
)
var (
// ErrUnknownCode is an error that represents unknown status code.
ErrUnknownCode = errors.New("unknown status code")
)

PeriodLimit is used to limit requests during a specific period. It has the following fields:

PeriodOption defines the method to customize a PeriodLimit.

Creates a new PeriodLimit instance.

func NewPeriodLimit(period, quota int, limitStore *redis.Redis, keyPrefix string, opts ...PeriodOption) *PeriodLimit
  • period: The time period in seconds for which the rate limit applies.
  • quota: The maximum number of allowed requests within the specified period.
  • limitStore: The Redis store instance used for keeping track of the limits.
  • keyPrefix: A prefix for the keys used in Redis to distinguish different limits.
  • opts: Optional customization options for the PeriodLimit instance.
package main
import (
"fmt"
"github.com/zeromicro/go-zero/core/stores/redis"
"limit"
)
func main() {
store := redis.New("localhost:6379")
limiter := limit.NewPeriodLimit(60, 10, store, "exampleKey")
result, err := limiter.Take("user1")
if err != nil {
fmt.Println("Error:", err)
return
}
switch result {
case limit.Allowed:
fmt.Println("Request allowed")
case limit.HitQuota:
fmt.Println("Hit the quota")
case limit.OverQuota:
fmt.Println("Over the quota")
default:
fmt.Println("Unknown status")
}
}

Requests a permit, returns the permit state.

func (h *PeriodLimit) Take(key string) (int, error)
  • key: The key to identify the requester. This is usually a unique identifier for the client or user making the request.
  • An integer representing the permit state (Allowed, HitQuota, OverQuota, or Unknown).
  • An error if something goes wrong during the request processing.

Requests a permit with context, returns the permit state.

func (h *PeriodLimit) TakeCtx(ctx context.Context, key string) (int, error)
  • ctx: The context to control the execution of this function, useful for timeouts and cancellations.
  • key: The key to identify the requester. This is usually a unique identifier for the client or user making the request.
  • An integer representing the permit state (Allowed, HitQuota, OverQuota, or Unknown).
  • An error if something goes wrong during the request processing.

Returns a PeriodOption to align the time period.

func Align() PeriodOption
  • A PeriodOption that can be used to configure a PeriodLimit to align its time periods. For example, aligning to the start of a day.
package main
import (
"fmt"
"github.com/zeromicro/go-zero/core/stores/redis"
"limit"
)
func main() {
store := redis.New("localhost:6379")
limiter := limit.NewPeriodLimit(86400, 5, store, "sms_limit", limit.Align())
result, err := limiter.Take("user1")
if err != nil {
fmt.Println("Error:", err)
return
}
switch result {
case limit.Allowed:
fmt.Println("SMS request allowed")
case limit.HitQuota:
fmt.Println("Hit the daily quota")
case limit.OverQuota:
fmt.Println("Over the daily quota")
default:
fmt.Println("Unknown status")
}
}