|
package utils |
|
|
|
import ( |
|
"sync" |
|
|
|
"golang.org/x/time/rate" |
|
) |
|
|
|
type RateLimiter struct { |
|
ips map[interface{}]*rate.Limiter |
|
mu *sync.RWMutex |
|
r rate.Limit |
|
b int |
|
} |
|
|
|
func NewRateLimiter(r rate.Limit, b int) *RateLimiter { |
|
i := &RateLimiter{ |
|
ips: make(map[interface{}]*rate.Limiter), |
|
mu: &sync.RWMutex{}, |
|
r: r, |
|
b: b, |
|
} |
|
|
|
return i |
|
} |
|
|
|
func (i *RateLimiter) AddIP(ip interface{}) *rate.Limiter { |
|
i.mu.Lock() |
|
defer i.mu.Unlock() |
|
|
|
limiter := rate.NewLimiter(i.r, i.b) |
|
|
|
i.ips[ip] = limiter |
|
|
|
return limiter |
|
} |
|
|
|
func (i *RateLimiter) GetLimiter(ip interface{}) *rate.Limiter { |
|
i.mu.Lock() |
|
limiter, exists := i.ips[ip] |
|
|
|
if !exists { |
|
i.mu.Unlock() |
|
return i.AddIP(ip) |
|
} |
|
|
|
i.mu.Unlock() |
|
|
|
return limiter |
|
} |
|
|