Documentation ¶
Overview ¶
Provides out-of-the-box rate limiting event-sifters.
Index ¶
- type Quota
- type QuotaForKinds
- type SifterUnit
- func (s *SifterUnit) Exclude(exclude func(*strfrui.Input) bool) *SifterUnit
- func (s *SifterUnit) RejectWithMsg(msg string) *SifterUnit
- func (s *SifterUnit) RejectWithMsgFromInput(getMsg func(*strfrui.Input) string) *SifterUnit
- func (s *SifterUnit) ShadowReject() *SifterUnit
- func (s *SifterUnit) Sift(input *strfrui.Input) (*strfrui.Result, error)
- type UserKey
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
QuotaPerDay creates a Quota with max rate of n per day.
func QuotaPerDuration ¶ added in v0.2.0
QuotaPerDuration creates a Quota with max rate of n per provided duration.
func QuotaPerHour ¶ added in v0.2.0
QuotaPerHour creates a Quota with max rate of n per hour.
func QuotaPerMin ¶ added in v0.2.0
QuotaPerMin creates a Quota with max rate of n per minute.
func QuotaPerSec ¶ added in v0.2.0
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.
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.