mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 18:36:57 +00:00
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package serverless
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// TokenBucketLimiter implements RateLimiter using a token bucket algorithm.
|
|
type TokenBucketLimiter struct {
|
|
mu sync.Mutex
|
|
tokens float64
|
|
max float64
|
|
refill float64 // tokens per second
|
|
lastTime time.Time
|
|
}
|
|
|
|
// NewTokenBucketLimiter creates a rate limiter with the given per-minute limit.
|
|
func NewTokenBucketLimiter(perMinute int) *TokenBucketLimiter {
|
|
perSecond := float64(perMinute) / 60.0
|
|
return &TokenBucketLimiter{
|
|
tokens: float64(perMinute), // start full
|
|
max: float64(perMinute),
|
|
refill: perSecond,
|
|
lastTime: time.Now(),
|
|
}
|
|
}
|
|
|
|
// Allow checks if a request should be allowed. Returns true if allowed.
|
|
func (t *TokenBucketLimiter) Allow(_ context.Context, _ string) (bool, error) {
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
|
|
now := time.Now()
|
|
elapsed := now.Sub(t.lastTime).Seconds()
|
|
t.lastTime = now
|
|
|
|
// Refill tokens
|
|
t.tokens += elapsed * t.refill
|
|
if t.tokens > t.max {
|
|
t.tokens = t.max
|
|
}
|
|
|
|
// Check if we have a token
|
|
if t.tokens < 1.0 {
|
|
return false, nil
|
|
}
|
|
|
|
t.tokens--
|
|
return true, nil
|
|
}
|