Skip to content
Snippets Groups Projects
Unverified Commit eb434b6f authored by Xin.Zh's avatar Xin.Zh Committed by GitHub
Browse files

Merge pull request #280 from flycash/feature/StrategyCreator

Ftr: Replace func(int, int) with TpsLimitStrategyCreator interface
parents 3fe96d35 720def0e
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,7 @@ import (
)
var (
tpsLimitStrategy = make(map[string]func(rate int, interval int) tps.TpsLimitStrategy)
tpsLimitStrategy = make(map[string]tps.TpsLimitStrategyCreator)
tpsLimiter = make(map[string]func() tps.TpsLimiter)
)
......@@ -39,11 +39,11 @@ func GetTpsLimiter(name string) tps.TpsLimiter {
return creator()
}
func SetTpsLimitStrategy(name string, creator func(rate int, interval int) tps.TpsLimitStrategy) {
func SetTpsLimitStrategy(name string, creator tps.TpsLimitStrategyCreator) {
tpsLimitStrategy[name] = creator
}
func GetTpsLimitStrategyCreator(name string) func(rate int, interval int) tps.TpsLimitStrategy {
func GetTpsLimitStrategyCreator(name string) tps.TpsLimitStrategyCreator {
creator, ok := tpsLimitStrategy[name]
if !ok {
panic("TpsLimitStrategy for " + name + " is not existing, make sure you have import the package " +
......
......@@ -33,8 +33,9 @@ const (
)
func init() {
extension.SetTpsLimitStrategy(FixedWindowKey, NewFixedWindowTpsLimitStrategyImpl)
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, NewFixedWindowTpsLimitStrategyImpl)
creator := &fixedWindowStrategyCreator{}
extension.SetTpsLimitStrategy(FixedWindowKey, creator)
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, creator)
}
/**
......@@ -76,7 +77,9 @@ func (impl *FixedWindowTpsLimitStrategyImpl) IsAllowable() bool {
return atomic.AddInt32(&impl.count, 1) <= impl.rate
}
func NewFixedWindowTpsLimitStrategyImpl(rate int, interval int) tps.TpsLimitStrategy {
type fixedWindowStrategyCreator struct{}
func (creator *fixedWindowStrategyCreator) Create(rate int, interval int) tps.TpsLimitStrategy {
return &FixedWindowTpsLimitStrategyImpl{
rate: int32(rate),
interval: int64(interval) * int64(time.Millisecond), // convert to ns
......
......@@ -27,12 +27,13 @@ import (
)
func TestFixedWindowTpsLimitStrategyImpl_IsAllowable(t *testing.T) {
strategy := NewFixedWindowTpsLimitStrategyImpl(2, 60000)
creator := &fixedWindowStrategyCreator{}
strategy := creator.Create(2, 60000)
assert.True(t, strategy.IsAllowable())
assert.True(t, strategy.IsAllowable())
assert.False(t, strategy.IsAllowable())
strategy = NewFixedWindowTpsLimitStrategyImpl(2, 2000)
strategy = creator.Create(2, 2000)
assert.True(t, strategy.IsAllowable())
assert.True(t, strategy.IsAllowable())
assert.False(t, strategy.IsAllowable())
......
......@@ -29,7 +29,7 @@ import (
)
func init() {
extension.SetTpsLimitStrategy("slidingWindow", NewSlidingWindowTpsLimitStrategyImpl)
extension.SetTpsLimitStrategy("slidingWindow", &slidingWindowStrategyCreator{})
}
/**
......@@ -80,7 +80,9 @@ func (impl *SlidingWindowTpsLimitStrategyImpl) IsAllowable() bool {
return false
}
func NewSlidingWindowTpsLimitStrategyImpl(rate int, interval int) tps.TpsLimitStrategy {
type slidingWindowStrategyCreator struct{}
func (creator *slidingWindowStrategyCreator) Create(rate int, interval int) tps.TpsLimitStrategy {
return &SlidingWindowTpsLimitStrategyImpl{
rate: rate,
interval: int64(interval) * int64(time.Millisecond),
......
......@@ -27,14 +27,15 @@ import (
)
func TestSlidingWindowTpsLimitStrategyImpl_IsAllowable(t *testing.T) {
strategy := NewSlidingWindowTpsLimitStrategyImpl(2, 60000)
creator := &slidingWindowStrategyCreator{}
strategy := creator.Create(2, 60000)
assert.True(t, strategy.IsAllowable())
assert.True(t, strategy.IsAllowable())
assert.False(t, strategy.IsAllowable())
time.Sleep(2100 * time.Millisecond)
assert.False(t, strategy.IsAllowable())
strategy = NewSlidingWindowTpsLimitStrategyImpl(2, 2000)
strategy = creator.Create(2, 2000)
assert.True(t, strategy.IsAllowable())
assert.True(t, strategy.IsAllowable())
assert.False(t, strategy.IsAllowable())
......
......@@ -27,7 +27,9 @@ import (
)
func init() {
extension.SetTpsLimitStrategy("threadSafeFixedWindow", NewThreadSafeFixedWindowTpsLimitStrategyImpl)
extension.SetTpsLimitStrategy("threadSafeFixedWindow", &threadSafeFixedWindowStrategyCreator{
fixedWindowStrategyCreator: &fixedWindowStrategyCreator{},
})
}
/**
......@@ -56,8 +58,12 @@ func (impl *ThreadSafeFixedWindowTpsLimitStrategyImpl) IsAllowable() bool {
return impl.fixedWindow.IsAllowable()
}
func NewThreadSafeFixedWindowTpsLimitStrategyImpl(rate int, interval int) tps.TpsLimitStrategy {
fixedWindowStrategy := NewFixedWindowTpsLimitStrategyImpl(rate, interval).(*FixedWindowTpsLimitStrategyImpl)
type threadSafeFixedWindowStrategyCreator struct {
fixedWindowStrategyCreator *fixedWindowStrategyCreator
}
func (creator *threadSafeFixedWindowStrategyCreator) Create(rate int, interval int) tps.TpsLimitStrategy {
fixedWindowStrategy := creator.fixedWindowStrategyCreator.Create(rate, interval).(*FixedWindowTpsLimitStrategyImpl)
return &ThreadSafeFixedWindowTpsLimitStrategyImpl{
fixedWindow: fixedWindowStrategy,
mutex: &sync.Mutex{},
......
......@@ -27,12 +27,13 @@ import (
)
func TestThreadSafeFixedWindowTpsLimitStrategyImpl_IsAllowable(t *testing.T) {
strategy := NewThreadSafeFixedWindowTpsLimitStrategyImpl(2, 60000)
creator := &threadSafeFixedWindowStrategyCreator{}
strategy := creator.Create(2, 60000)
assert.True(t, strategy.IsAllowable())
assert.True(t, strategy.IsAllowable())
assert.False(t, strategy.IsAllowable())
strategy = NewThreadSafeFixedWindowTpsLimitStrategyImpl(2, 2000)
strategy = creator.Create(2, 2000)
assert.True(t, strategy.IsAllowable())
assert.True(t, strategy.IsAllowable())
assert.False(t, strategy.IsAllowable())
......
......@@ -148,7 +148,7 @@ func (limiter MethodServiceTpsLimiterImpl) IsAllowable(url common.URL, invocatio
limitStrategyConfig := url.GetParam(methodConfigPrefix+constant.TPS_LIMIT_STRATEGY_KEY,
url.GetParam(constant.TPS_LIMIT_STRATEGY_KEY, constant.DEFAULT_KEY))
limitStateCreator := extension.GetTpsLimitStrategyCreator(limitStrategyConfig)
limitState, _ = limiter.tpsState.LoadOrStore(limitTarget, limitStateCreator(int(limitRate), int(limitInterval)))
limitState, _ = limiter.tpsState.LoadOrStore(limitTarget, limitStateCreator.Create(int(limitRate), int(limitInterval)))
return limitState.(tps.TpsLimitStrategy).IsAllowable()
}
......
......@@ -48,10 +48,12 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_Only_Service_Level(t *testing.T
mockStrategyImpl := NewMockTpsLimitStrategy(ctrl)
mockStrategyImpl.EXPECT().IsAllowable().Return(true).Times(1)
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, func(rate int, interval int) tps.TpsLimitStrategy {
assert.Equal(t, 20, rate)
assert.Equal(t, 60000, interval)
return mockStrategyImpl
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, &mockStrategyCreator{
rate: 40,
interval: 60000,
t: t,
strategy: mockStrategyImpl,
})
limiter := GetMethodServiceTpsLimiter()
......@@ -95,10 +97,12 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_Method_Level_Override(t *testin
mockStrategyImpl := NewMockTpsLimitStrategy(ctrl)
mockStrategyImpl.EXPECT().IsAllowable().Return(true).Times(1)
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, func(rate int, interval int) tps.TpsLimitStrategy {
assert.Equal(t, 40, rate)
assert.Equal(t, 7000, interval)
return mockStrategyImpl
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, &mockStrategyCreator{
rate: 40,
interval: 7000,
t: t,
strategy: mockStrategyImpl,
})
limiter := GetMethodServiceTpsLimiter()
......@@ -123,13 +127,28 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_Both_Method_And_Service(t *test
mockStrategyImpl := NewMockTpsLimitStrategy(ctrl)
mockStrategyImpl.EXPECT().IsAllowable().Return(true).Times(1)
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, func(rate int, interval int) tps.TpsLimitStrategy {
assert.Equal(t, 40, rate)
assert.Equal(t, 3000, interval)
return mockStrategyImpl
extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, &mockStrategyCreator{
rate: 40,
interval: 3000,
t: t,
strategy: mockStrategyImpl,
})
limiter := GetMethodServiceTpsLimiter()
result := limiter.IsAllowable(*invokeUrl, invoc)
assert.True(t, result)
}
type mockStrategyCreator struct {
rate int
interval int
t *testing.T
strategy tps.TpsLimitStrategy
}
func (creator *mockStrategyCreator) Create(rate int, interval int) tps.TpsLimitStrategy {
assert.Equal(creator.t, creator.rate, rate)
assert.Equal(creator.t, creator.interval, interval)
return creator.strategy
}
......@@ -34,3 +34,7 @@ package tps
type TpsLimitStrategy interface {
IsAllowable() bool
}
type TpsLimitStrategyCreator interface {
Create(rate int, interval int) TpsLimitStrategy
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment