1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- // golimiter.go
- package golimiter
- import (
- "sync"
- "time"
- )
- // TokenBucket represents a rate limiting mechanism based on the token bucket algorithm.
- type TokenBucket struct {
- capacity int // Maximum number of tokens the bucket can hold
- tokens int // Current number of tokens in the bucket
- fillRate int // Rate at which tokens are added to the bucket (tokens per second)
- lastTimestamp time.Time // Timestamp of the last token retrieval or addition
- expirationTime time.Time // Time when the bucket will expire and be removed from the manager
- mu sync.Mutex // Mutex for synchronization
- }
- // NewTokenBucket creates a new TokenBucket instance with the specified parameters.
- func NewTokenBucket(capacity, fillRate int, bucketLifetime time.Duration) *TokenBucket {
- return &TokenBucket{
- capacity: capacity,
- tokens: capacity,
- fillRate: fillRate,
- lastTimestamp: time.Now(),
- expirationTime: time.Now().Add(bucketLifetime),
- }
- }
- // TakeToken tries to retrieve a token from the bucket. Returns true if successful, false otherwise.
- // AddTokensToBucket adds tokens to the bucket based on the elapsed time and fill rate.
- func (tb *TokenBucket) AddTokensToBucket() {
- tb.mu.Lock()
- defer tb.mu.Unlock()
- currentTime := time.Now()
- elapsed := currentTime.Sub(tb.lastTimestamp).Milliseconds()
- fillAmount := int(elapsed) * tb.fillRate / 1000
- tb.tokens = tb.tokens + fillAmount
- if tb.tokens > tb.capacity {
- tb.tokens = tb.capacity
- }
- tb.lastTimestamp = time.Now()
- }
- // TakeToken tries to retrieve a token from the bucket. Returns true if successful, false otherwise.
- func (tb *TokenBucket) TakeToken() bool {
- tb.AddTokensToBucket()
- tb.mu.Lock()
- defer tb.mu.Unlock()
- if tb.tokens > 0 {
- tb.tokens--
- return true
- }
- return false
- }
|