ratelimit

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2024 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Provides out-of-the-box rate limiting event-sifters.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Quota

type Quota throttled.RateQuota

Quota describes the number of requests allowed per time period with burst.

You can concisely create instants of Quota using functions QuotaPerSec, QuotaPerMin, QuotaPerHour and so on. The Quota created by these constructors doesn't allow any bursts. To allow bursts, use Quota.WithBurst.

func QuotaPerDay added in v0.2.0

func QuotaPerDay(n int) Quota

QuotaPerDay creates a Quota with max rate of n per day.

func QuotaPerDuration added in v0.2.0

func QuotaPerDuration(n int, d time.Duration) Quota

QuotaPerDuration creates a Quota with max rate of n per provided duration.

func QuotaPerHour added in v0.2.0

func QuotaPerHour(n int) Quota

QuotaPerHour creates a Quota with max rate of n per hour.

func QuotaPerMin added in v0.2.0

func QuotaPerMin(n int) Quota

QuotaPerMin creates a Quota with max rate of n per minute.

func QuotaPerSec added in v0.2.0

func QuotaPerSec(n int) Quota

QuotaPerSec creates a Quota with max rate of n per second.

func (Quota) ForKinds added in v0.2.0

func (q Quota) ForKinds(kinds ...int) QuotaForKinds

ForKinds makes the Quota q be only applied to events of the given set of kinds.

func (Quota) ForKindsMatching added in v0.2.0

func (q Quota) ForKindsMatching(matchKind func(int) bool) QuotaForKinds

ForKindsMatching makes the Quota q be only applied to events of kinds that match the given matcher function.

You can use kind matchers defined in github.com/jiftechnify/strfrui/sifters, such as github.com/jiftechnify/strfrui/sifters.KindsAllReplaceable.

func (Quota) WithBurst added in v0.2.0

func (q Quota) WithBurst(maxBurst int) Quota

WithBurst creates new Quota that allows bursts, with max rate of q.

type QuotaForKinds

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

QuotaForKinds defines a quota of write requests of specific kinds of events.

This type is exposed only for document organization purpose. You shouldn't initialize this struct directly.

type SifterUnit

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

SifterUnit is base structure of rate-limiting event-sifter logic.

If it comes to reject inputs, each built-in sifter responds to the client with its own predefined message. If you want to customize the rejection behavior, use SifterUnit.RejectWithMsg, SifterUnit.RejectWithMsgFromInput or SifterUnit.ShadowReject.

This type is exposed only for document organization purpose. You shouldn't initialize this struct directly.

func ByUser

func ByUser(quota Quota, uk UserKey) *SifterUnit

ByUser creates a event-sifter that imposes rate limit on event write request per user.

"Users" are identified by the source IP address or the pubkey of the event, depending on the given UserKey.

Note that this doesn't impose a rate limit to events not from end-users (i.e. events imported from other relays).

Example
package main

import (
	"github.com/jiftechnify/strfrui"
	"github.com/jiftechnify/strfrui/sifters"
	"github.com/jiftechnify/strfrui/sifters/ratelimit"
)

func main() {
	rateLimiter := ratelimit.ByUser(
		// 500 events/h per user, allowing burst up to 50 events
		ratelimit.QuotaPerHour(500).WithBurst(50),
		// "users" are identified by the pubkey
		ratelimit.PubKey,
	).
		// exclude all ephemeral events from rate limiting
		Exclude(func(input *strfrui.Input) bool {
			return sifters.KindsAllEphemeral(input.Event.Kind)
		})

	strfrui.New(rateLimiter).Run()
}
Output:

Example (Pipeline)
package main

import (
	"github.com/jiftechnify/strfrui"
	"github.com/jiftechnify/strfrui/sifters"
	"github.com/jiftechnify/strfrui/sifters/ratelimit"
)

func main() {
	// Of course, rate limiters can be composed with other sifters!
	rateLimiter := ratelimit.ByUser(
		ratelimit.QuotaPerHour(500).WithBurst(50),
		ratelimit.PubKey,
	)
	shortKind1 := sifters.WithMod(
		sifters.ContentMatcher(func(s string) (bool, error) {
			return len(s) <= 140, nil
		}, sifters.Allow)).OnlyIf(sifters.KindList([]int{1}, sifters.Allow))

	strfrui.New(sifters.Pipeline(
		rateLimiter,
		shortKind1,
	)).Run()
}
Output:

func ByUserAndKind

func ByUserAndKind(quotas []QuotaForKinds, uk UserKey) *SifterUnit

ByUserAndKind creates a event-sifter that imposes rate limit on event write request per user and event kind. The quota for each event kind is specified by the given list of QuotaForKinds. For event kinds for which a quota is not defined, no rate limit is imposed.

"Users" are identified by the source IP address or the pubkey of the event, depending on the given UserKey.

Note that this doesn't impose a rate limit to events not from end-users (i.e. events imported from other relays).

Example
package main

import (
	"github.com/jiftechnify/strfrui"
	"github.com/jiftechnify/strfrui/sifters/ratelimit"
)

func main() {
	limiter := ratelimit.ByUserAndKind([]ratelimit.QuotaForKinds{
		// 100 kind:1 events/h per user, allowing burst up to 10 events
		ratelimit.QuotaPerHour(100).WithBurst(10).ForKinds(1),
		// 200 kind:7 events/h per user, allowing burst up to 50 events
		ratelimit.QuotaPerHour(200).WithBurst(50).ForKinds(7),
	}, ratelimit.PubKey)

	strfrui.New(limiter).Run()
}
Output:

func (*SifterUnit) Exclude

func (s *SifterUnit) Exclude(exclude func(*strfrui.Input) bool) *SifterUnit

Exclude makes the rate-limiting sifter exclude inputs that match given function from rate-limiting.

func (*SifterUnit) RejectWithMsg

func (s *SifterUnit) RejectWithMsg(msg string) *SifterUnit

RejectWithMsg makes the sifter reject the input with the given message.

func (*SifterUnit) RejectWithMsgFromInput

func (s *SifterUnit) RejectWithMsgFromInput(getMsg func(*strfrui.Input) string) *SifterUnit

RejectWithMsgFromInput makes the sifter reject the input with the message derived from the input by the given function.

func (*SifterUnit) ShadowReject

func (s *SifterUnit) ShadowReject() *SifterUnit

ShadowReject sets the sifter's rejection behavior to "shadow-reject", which pretend to accept the input but actually reject it.

func (*SifterUnit) Sift

func (s *SifterUnit) Sift(input *strfrui.Input) (*strfrui.Result, error)

type UserKey

type UserKey int

UserKey specifies what key should we use to identify a user for per-user rate limiting.

const (
	// Use the source IP address of an input as an user identifier.
	// In this mode, rate limit is not applied if the source of events can't be determined.
	IPAddr UserKey = iota + 1

	// Use the pubkey of an event as an user identifier.
	PubKey
)

Jump to

Keyboard shortcuts

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