service: add limiter.scope option

This commit is contained in:
ginuerzh
2025-01-20 23:22:58 +08:00
parent bf36bdc680
commit 379d9a73ad
80 changed files with 374 additions and 685 deletions
+81 -13
View File
@@ -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
}