limiter

package
v0.0.0-...-1d0540f Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2023 License: MIT Imports: 4 Imported by: 0

README

Limiter

The "limiter" subpackage provides rate limiting functionality with two different implementations: RingLimiter and HeapLimiter.

HeapLimiter sorts on insertion based on the value (timestamp) while RingLimiter assumed order based on insertion. So this would be used when you insertions may be asynchronous and not in order and you need every bit of accuracy. Because of the extra operations, heap is more expensive. In most cases RingLimiter will be faster and sufficient.

Both methods are very fast, here is benchmark comparing them:

goos: darwin
goarch: arm64
pkg: github.com/parkerroan/ratebroker/limiter
BenchmarkRingLimiter-10    	29388708	        40.32 ns/op	      24 B/op	       1 allocs/op
BenchmarkHeapLimiter-10    	15745207	        71.66 ns/op	      80 B/op	       1 allocs/op

Features

  • Two rate limiting strategies: Ring Buffer and Min Heap.
  • Thread-safe operations using mutex locks.
  • Customizable rate limiting parameters: size and window.

Usage

First, import the limiter package in your Go code:

import "github.com/yourusername/yourproject/limiter"

Then, create a new RingLimiter or HeapLimiter with the desired size and window:

rl := limiter.NewRingLimiter(100, 1 * time.Minute)
hl := limiter.NewHeapLimiter(100, 1 * time.Minute)

You can then use the Try, Accept, and TryAccept methods to enforce rate limits:

ok := rl.TryAccept(time.Now())

Contributing

Contributions are welcome. Please submit a pull request or create an issue to discuss the changes.

License

This project is licensed under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHeapLimiterConstructorFunc

func NewHeapLimiterConstructorFunc() func(int, time.Duration) Limiter

NewHeapLimiterConstructorFunc returns a function that creates a new HeapLimiter.

func NewRingLimiterConstructorFunc

func NewRingLimiterConstructorFunc() func(int, time.Duration) Limiter

NewRingLimiterConstructorFunc returns a function that creates a new RingLimiter. This is used by default in the Broker.

Types

type HeapLimiter

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

HeapLimiter is an implementation of the Limiter interface using a min-heap. This would be used if more accuracy is needed because the heap is sorted by the timestamp value not the order of the requests like with the ring buffer. This is also more expensive than the ring buffer.

func NewHeapLimiter

func NewHeapLimiter(size int, window time.Duration) *HeapLimiter

NewHeapLimiter returns a new HeapLimiter.

func (*HeapLimiter) Accept

func (hl *HeapLimiter) Accept(now time.Time)

Accept implements the Limiter interface for the HeapLimiter. This is used when the request is accepted and added to the heap.

func (*HeapLimiter) LimitDetails

func (hl *HeapLimiter) LimitDetails() (int, time.Duration)

LimitDetails returns the size and window of the limiter.

func (*HeapLimiter) Try

func (hl *HeapLimiter) Try(now time.Time) bool

Try implements the Limiter interface for the HeapLimiter. This is used to check if the request is within the rate limits.

func (*HeapLimiter) TryAccept

func (hl *HeapLimiter) TryAccept(now time.Time) bool

TryAccept implements the Limiter interface for the HeapLimiter. This is used to check if the request is within the rate limits and if it is, it's added to the heap.

type Limiter

type Limiter interface {
	// Try checks if it's within the rate limits.
	Try(time.Time) bool
	// Accept logs a new request to the limiter.
	Accept(time.Time)
	// TryAccept checks if it's within the rate limits and logs a new request to the limiter.
	TryAccept(time.Time) bool
	// LimitDetails returns the size and window of the limiter.
	LimitDetails() (int, time.Duration)
}

Limiter is the interface that abstracts the limitations functionality.

type RingLimiter

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

RingLimiter is an implementation of the Limiter interface using a ring buffer. This is more performant than the HeapLimiter as it doesn't need to sort the requests by value and it uses a fixed size array.

func NewRingLimiter

func NewRingLimiter(size int, window time.Duration) *RingLimiter

NewRingLimiterInstance creates a RingLimiter.

func (*RingLimiter) Accept

func (rl *RingLimiter) Accept(now time.Time)

Accept adds a new request to the ring buffer.

func (*RingLimiter) LimitDetails

func (rl *RingLimiter) LimitDetails() (int, time.Duration)

LimitDetails returns the size and window of the limiter.

func (*RingLimiter) Try

func (rl *RingLimiter) Try(now time.Time) bool

Try checks if it's within the rate limits.

func (*RingLimiter) TryAccept

func (rl *RingLimiter) TryAccept(now time.Time) bool

TryAccept checks if it's within the rate limits and adds a new request to the ring buffer.

Jump to

Keyboard shortcuts

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