service: add limiter.scope option
This commit is contained in:
@@ -8,23 +8,73 @@ import (
|
||||
"github.com/go-gost/core/limiter/traffic"
|
||||
)
|
||||
|
||||
type cachedTrafficLimiter struct {
|
||||
inLimits *Cache
|
||||
outLimits *Cache
|
||||
limiter traffic.TrafficLimiter
|
||||
const (
|
||||
defaultRefreshInterval = 30 * time.Second
|
||||
defaultCleanupInterval = 60 * time.Second
|
||||
)
|
||||
|
||||
type options struct {
|
||||
refreshInterval time.Duration
|
||||
cleanupInterval time.Duration
|
||||
scope string
|
||||
}
|
||||
|
||||
func NewCachedTrafficLimiter(limiter traffic.TrafficLimiter, refreshInterval time.Duration, cleanupInterval time.Duration) traffic.TrafficLimiter {
|
||||
type Option func(*options)
|
||||
|
||||
func RefreshIntervalOption(interval time.Duration) Option {
|
||||
return func(o *options) {
|
||||
o.refreshInterval = interval
|
||||
}
|
||||
}
|
||||
|
||||
func CleanupIntervalOption(interval time.Duration) Option {
|
||||
return func(o *options) {
|
||||
o.cleanupInterval = interval
|
||||
}
|
||||
}
|
||||
|
||||
func ScopeOption(scope string) Option {
|
||||
return func(o *options) {
|
||||
o.scope = scope
|
||||
}
|
||||
}
|
||||
|
||||
type cachedTrafficLimiter struct {
|
||||
inLimits *Cache
|
||||
outLimits *Cache
|
||||
limiter traffic.TrafficLimiter
|
||||
options options
|
||||
}
|
||||
|
||||
func NewCachedTrafficLimiter(limiter traffic.TrafficLimiter, opts ...Option) traffic.TrafficLimiter {
|
||||
if limiter == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var options options
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
if options.refreshInterval == 0 {
|
||||
options.refreshInterval = defaultRefreshInterval
|
||||
}
|
||||
if options.refreshInterval < time.Second {
|
||||
options.refreshInterval = time.Second
|
||||
}
|
||||
|
||||
if options.cleanupInterval == 0 {
|
||||
options.cleanupInterval = defaultCleanupInterval
|
||||
}
|
||||
if options.cleanupInterval < time.Second {
|
||||
options.cleanupInterval = time.Second
|
||||
}
|
||||
|
||||
lim := &cachedTrafficLimiter{
|
||||
inLimits: NewCache(cleanupInterval),
|
||||
outLimits: NewCache(cleanupInterval),
|
||||
limiter: limiter,
|
||||
refreshInterval: refreshInterval,
|
||||
inLimits: NewCache(options.cleanupInterval),
|
||||
outLimits: NewCache(options.cleanupInterval),
|
||||
limiter: limiter,
|
||||
options: options,
|
||||
}
|
||||
return lim
|
||||
}
|
||||
@@ -34,6 +84,15 @@ func (p *cachedTrafficLimiter) In(ctx context.Context, key string, opts ...limit
|
||||
return nil
|
||||
}
|
||||
|
||||
var options limiter.Options
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
if p.options.scope != "" && p.options.scope != options.Scope {
|
||||
return nil
|
||||
}
|
||||
|
||||
item := p.inLimits.Get(key)
|
||||
lim, _ := item.Value().(traffic.Limiter)
|
||||
if !item.Expired() {
|
||||
@@ -45,11 +104,11 @@ func (p *cachedTrafficLimiter) In(ctx context.Context, key string, opts ...limit
|
||||
limNew = lim
|
||||
}
|
||||
if item == nil || !p.equal(lim, limNew) {
|
||||
p.inLimits.Set(key, NewItem(limNew, p.refreshInterval))
|
||||
p.inLimits.Set(key, NewItem(limNew, p.options.refreshInterval))
|
||||
return limNew
|
||||
}
|
||||
|
||||
p.inLimits.Set(key, NewItem(lim, p.refreshInterval))
|
||||
p.inLimits.Set(key, NewItem(lim, p.options.refreshInterval))
|
||||
|
||||
return lim
|
||||
}
|
||||
@@ -59,6 +118,15 @@ func (p *cachedTrafficLimiter) Out(ctx context.Context, key string, opts ...limi
|
||||
return nil
|
||||
}
|
||||
|
||||
var options limiter.Options
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
if p.options.scope != "" && p.options.scope != options.Scope {
|
||||
return nil
|
||||
}
|
||||
|
||||
item := p.outLimits.Get(key)
|
||||
lim, _ := item.Value().(traffic.Limiter)
|
||||
if !item.Expired() {
|
||||
@@ -70,11 +138,11 @@ func (p *cachedTrafficLimiter) Out(ctx context.Context, key string, opts ...limi
|
||||
limNew = lim
|
||||
}
|
||||
if item == nil || !p.equal(lim, limNew) {
|
||||
p.outLimits.Set(key, NewItem(limNew, p.refreshInterval))
|
||||
p.outLimits.Set(key, NewItem(limNew, p.options.refreshInterval))
|
||||
return limNew
|
||||
}
|
||||
|
||||
p.outLimits.Set(key, NewItem(lim, p.refreshInterval))
|
||||
p.outLimits.Set(key, NewItem(lim, p.options.refreshInterval))
|
||||
|
||||
return lim
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user