Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
2
22a7f0099
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Summer2022
22a7f0099
Commits
4b238d3e
Commit
4b238d3e
authored
4 years ago
by
Ming Deng
Committed by
GitHub
4 years ago
Browse files
Options
Downloads
Plain Diff
Merge pull request #490 from flycash/doc-comments
Add comments for ServiceMethodLimiter
parents
30fafdb3
c4df1e68
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
filter/filter_impl/tps/tps_limiter_method_service.go
+23
-2
23 additions, 2 deletions
filter/filter_impl/tps/tps_limiter_method_service.go
filter/tps_limiter.go
+1
-0
1 addition, 0 deletions
filter/tps_limiter.go
with
24 additions
and
2 deletions
filter/filter_impl/tps/tps_limiter_method_service.go
+
23
−
2
View file @
4b238d3e
...
...
@@ -115,7 +115,12 @@ type MethodServiceTpsLimiterImpl struct {
tpsState
*
concurrent
.
Map
}
// IsAllowable ...
// IsAllowable based on method-level and service-level.
// The method-level has high priority which means that if there is any rate limit configuration for the method,
// the service-level rate limit strategy will be ignored.
// The key point is how to keep thread-safe
// This implementation use concurrent map + loadOrStore to make implementation thread-safe
// You can image that even multiple threads create limiter, but only one could store the limiter into tpsState
func
(
limiter
MethodServiceTpsLimiterImpl
)
IsAllowable
(
url
common
.
URL
,
invocation
protocol
.
Invocation
)
bool
{
methodConfigPrefix
:=
"methods."
+
invocation
.
MethodName
()
+
"."
...
...
@@ -123,23 +128,30 @@ func (limiter MethodServiceTpsLimiterImpl) IsAllowable(url common.URL, invocatio
methodLimitRateConfig
:=
url
.
GetParam
(
methodConfigPrefix
+
constant
.
TPS_LIMIT_RATE_KEY
,
""
)
methodIntervalConfig
:=
url
.
GetParam
(
methodConfigPrefix
+
constant
.
TPS_LIMIT_INTERVAL_KEY
,
""
)
// service-level tps limit
limitTarget
:=
url
.
ServiceKey
()
// method-level tps limit
if
len
(
methodIntervalConfig
)
>
0
||
len
(
methodLimitRateConfig
)
>
0
{
// it means that if the method-level rate limit exist, we will use method-level rate limit strategy
limitTarget
=
limitTarget
+
"#"
+
invocation
.
MethodName
()
}
// looking up the limiter from 'cache'
limitState
,
found
:=
limiter
.
tpsState
.
Load
(
limitTarget
)
if
found
{
// the limiter has been cached, we return its result
return
limitState
.
(
filter
.
TpsLimitStrategy
)
.
IsAllowable
()
}
// we could not find the limiter, and try to create one.
limitRate
:=
getLimitConfig
(
methodLimitRateConfig
,
url
,
invocation
,
constant
.
TPS_LIMIT_RATE_KEY
,
constant
.
DEFAULT_TPS_LIMIT_RATE
)
if
limitRate
<
0
{
// the limitTarget is not necessary to be limited.
return
true
}
...
...
@@ -150,13 +162,20 @@ func (limiter MethodServiceTpsLimiterImpl) IsAllowable(url common.URL, invocatio
panic
(
fmt
.
Sprintf
(
"The interval must be positive, please check your configuration! url: %s"
,
url
.
String
()))
}
// find the strategy config and then create one
limitStrategyConfig
:=
url
.
GetParam
(
methodConfigPrefix
+
constant
.
TPS_LIMIT_STRATEGY_KEY
,
url
.
GetParam
(
constant
.
TPS_LIMIT_STRATEGY_KEY
,
constant
.
DEFAULT_KEY
))
limitStateCreator
:=
extension
.
GetTpsLimitStrategyCreator
(
limitStrategyConfig
)
// we using loadOrStore to ensure thread-safe
limitState
,
_
=
limiter
.
tpsState
.
LoadOrStore
(
limitTarget
,
limitStateCreator
.
Create
(
int
(
limitRate
),
int
(
limitInterval
)))
return
limitState
.
(
filter
.
TpsLimitStrategy
)
.
IsAllowable
()
}
// getLimitConfig will try to fetch the configuration from url.
// If we can convert the methodLevelConfig to int64, return;
// Or, we will try to look up server-level configuration and then convert it to int64
func
getLimitConfig
(
methodLevelConfig
string
,
url
common
.
URL
,
invocation
protocol
.
Invocation
,
...
...
@@ -172,6 +191,8 @@ func getLimitConfig(methodLevelConfig string,
return
result
}
// actually there is no method-level configuration, so we use the service-level configuration
result
,
err
:=
strconv
.
ParseInt
(
url
.
GetParam
(
configKey
,
defaultVal
),
0
,
0
)
if
err
!=
nil
{
...
...
@@ -183,7 +204,7 @@ func getLimitConfig(methodLevelConfig string,
var
methodServiceTpsLimiterInstance
*
MethodServiceTpsLimiterImpl
var
methodServiceTpsLimiterOnce
sync
.
Once
// GetMethodServiceTpsLimiter
..
.
// GetMethodServiceTpsLimiter
will return an MethodServiceTpsLimiterImpl instance
.
func
GetMethodServiceTpsLimiter
()
filter
.
TpsLimiter
{
methodServiceTpsLimiterOnce
.
Do
(
func
()
{
methodServiceTpsLimiterInstance
=
&
MethodServiceTpsLimiterImpl
{
...
...
This diff is collapsed.
Click to expand it.
filter/tps_limiter.go
+
1
−
0
View file @
4b238d3e
...
...
@@ -34,5 +34,6 @@ import (
* tps.limiter: "the name of limiter",
*/
type
TpsLimiter
interface
{
// IsAllowable will check whether this invocation should be enabled for further process
IsAllowable
(
common
.
URL
,
protocol
.
Invocation
)
bool
}
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment