@@ -20,7 +20,8 @@ type yamlReplaces struct {
20
20
type YamlRateLimit struct {
21
21
RequestsPerUnit uint32 `yaml:"requests_per_unit"`
22
22
Unit string
23
- Unlimited bool `yaml:"unlimited"`
23
+ UnitMultiplier * uint32 `yaml:"unit_multiplier"`
24
+ Unlimited bool `yaml:"unlimited"`
24
25
Name string
25
26
Replaces []yamlReplaces
26
27
}
@@ -68,23 +69,26 @@ var validKeys = map[string]bool{
68
69
"name" : true ,
69
70
"replaces" : true ,
70
71
"detailed_metric" : true ,
72
+ "unit_multiplier" : true ,
71
73
}
72
74
73
75
// Create a new rate limit config entry.
74
76
// @param requestsPerUnit supplies the requests per unit of time for the entry.
75
77
// @param unit supplies the unit of time for the entry.
78
+ // @param unitMultiplier supplies the multiplier for the unit of time for the entry.
76
79
// @param rlStats supplies the stats structure associated with the RateLimit
77
80
// @param unlimited supplies whether the rate limit is unlimited
78
81
// @return the new config entry.
79
82
func NewRateLimit (requestsPerUnit uint32 , unit pb.RateLimitResponse_RateLimit_Unit , rlStats stats.RateLimitStats ,
80
- unlimited bool , shadowMode bool , name string , replaces []string , detailedMetric bool ) * RateLimit {
81
-
83
+ unlimited bool , shadowMode bool , name string , replaces []string , detailedMetric bool , unitMultiplier uint32 ,
84
+ ) * RateLimit {
82
85
return & RateLimit {
83
86
FullKey : rlStats .GetKey (),
84
87
Stats : rlStats ,
85
88
Limit : & pb.RateLimitResponse_RateLimit {
86
89
RequestsPerUnit : requestsPerUnit ,
87
90
Unit : unit ,
91
+ UnitMultiplier : unitMultiplier ,
88
92
},
89
93
Unlimited : unlimited ,
90
94
ShadowMode : shadowMode ,
@@ -99,8 +103,8 @@ func (this *rateLimitDescriptor) dump() string {
99
103
ret := ""
100
104
if this .limit != nil {
101
105
ret += fmt .Sprintf (
102
- "%s: unit=%s requests_per_unit=%d, shadow_mode: %t\n " , this .limit .FullKey ,
103
- this .limit .Limit .Unit .String (), this .limit .Limit .RequestsPerUnit , this .limit .ShadowMode )
106
+ "%s: unit=%s, unit_multiplier=%d, requests_per_unit=%d, shadow_mode: %t\n " , this .limit .FullKey ,
107
+ this .limit .Limit .Unit .String (), this .limit .Limit .UnitMultiplier , this . limit . Limit . RequestsPerUnit , this .limit .ShadowMode )
104
108
}
105
109
for _ , descriptor := range this .descriptors {
106
110
ret += descriptor .dump ()
@@ -143,8 +147,7 @@ func (this *rateLimitDescriptor) loadDescriptors(config RateLimitConfigToLoad, p
143
147
if descriptorConfig .RateLimit != nil {
144
148
unlimited := descriptorConfig .RateLimit .Unlimited
145
149
146
- value , present :=
147
- pb .RateLimitResponse_RateLimit_Unit_value [strings .ToUpper (descriptorConfig .RateLimit .Unit )]
150
+ value , present := pb .RateLimitResponse_RateLimit_Unit_value [strings .ToUpper (descriptorConfig .RateLimit .Unit )]
148
151
validUnit := present && value != int32 (pb .RateLimitResponse_RateLimit_UNKNOWN )
149
152
150
153
if unlimited {
@@ -159,6 +162,18 @@ func (this *rateLimitDescriptor) loadDescriptors(config RateLimitConfigToLoad, p
159
162
fmt .Sprintf ("invalid rate limit unit '%s'" , descriptorConfig .RateLimit .Unit )))
160
163
}
161
164
165
+ var unitMultiplier uint32
166
+ if descriptorConfig .RateLimit .UnitMultiplier == nil {
167
+ unitMultiplier = 1
168
+ } else {
169
+ unitMultiplier = * descriptorConfig .RateLimit .UnitMultiplier
170
+ if unitMultiplier == 0 {
171
+ panic (newRateLimitConfigError (
172
+ config .Name ,
173
+ "invalid unit multiplier of 0" ))
174
+ }
175
+ }
176
+
162
177
replaces := make ([]string , len (descriptorConfig .RateLimit .Replaces ))
163
178
for i , e := range descriptorConfig .RateLimit .Replaces {
164
179
replaces [i ] = e .Name
@@ -168,10 +183,12 @@ func (this *rateLimitDescriptor) loadDescriptors(config RateLimitConfigToLoad, p
168
183
descriptorConfig .RateLimit .RequestsPerUnit , pb .RateLimitResponse_RateLimit_Unit (value ),
169
184
statsManager .NewStats (newParentKey ), unlimited , descriptorConfig .ShadowMode ,
170
185
descriptorConfig .RateLimit .Name , replaces , descriptorConfig .DetailedMetric ,
186
+ unitMultiplier ,
171
187
)
188
+
172
189
rateLimitDebugString = fmt .Sprintf (
173
- " ratelimit={requests_per_unit=%d, unit=%s, unlimited=%t, shadow_mode=%t}" , rateLimit .Limit .RequestsPerUnit ,
174
- rateLimit .Limit .Unit .String (), rateLimit .Unlimited , rateLimit .ShadowMode )
190
+ " ratelimit={requests_per_unit=%d, unit=%s, unit_multiplier=%d, unlimited=%t, shadow_mode=%t}" , rateLimit .Limit .RequestsPerUnit ,
191
+ rateLimit .Limit .Unit .String (), unitMultiplier , rateLimit .Unlimited , rateLimit .ShadowMode )
175
192
176
193
for _ , replaces := range descriptorConfig .RateLimit .Replaces {
177
194
if replaces .Name == "" {
@@ -277,8 +294,8 @@ func (this *rateLimitConfigImpl) Dump() string {
277
294
}
278
295
279
296
func (this * rateLimitConfigImpl ) GetLimit (
280
- ctx context.Context , domain string , descriptor * pb_struct.RateLimitDescriptor ) * RateLimit {
281
-
297
+ ctx context.Context , domain string , descriptor * pb_struct.RateLimitDescriptor ,
298
+ ) * RateLimit {
282
299
logger .Debugf ("starting get limit lookup" )
283
300
var rateLimit * RateLimit = nil
284
301
value := this .domains [domain ]
@@ -300,6 +317,7 @@ func (this *rateLimitConfigImpl) GetLimit(
300
317
"" ,
301
318
[]string {},
302
319
false ,
320
+ 1 ,
303
321
)
304
322
return rateLimit
305
323
}
@@ -352,7 +370,10 @@ func (this *rateLimitConfigImpl) GetLimit(
352
370
descriptorsMap = nextDescriptor .descriptors
353
371
} else {
354
372
if rateLimit != nil && rateLimit .DetailedMetric {
355
- rateLimit = NewRateLimit (rateLimit .Limit .RequestsPerUnit , rateLimit .Limit .Unit , this .statsManager .NewStats (rateLimit .FullKey ), rateLimit .Unlimited , rateLimit .ShadowMode , rateLimit .Name , rateLimit .Replaces , rateLimit .DetailedMetric )
373
+ rateLimit = NewRateLimit (rateLimit .Limit .RequestsPerUnit , rateLimit .Limit .Unit ,
374
+ this .statsManager .NewStats (rateLimit .FullKey ), rateLimit .Unlimited ,
375
+ rateLimit .ShadowMode , rateLimit .Name , rateLimit .Replaces ,
376
+ rateLimit .DetailedMetric , rateLimit .Limit .UnitMultiplier )
356
377
}
357
378
358
379
break
@@ -417,8 +438,8 @@ func ConfigFileContentToYaml(fileName, content string) *YamlRoot {
417
438
// @param mergeDomainConfigs defines whether multiple configurations referencing the same domain will be merged or rejected throwing an error.
418
439
// @return a new config.
419
440
func NewRateLimitConfigImpl (
420
- configs []RateLimitConfigToLoad , statsManager stats.Manager , mergeDomainConfigs bool ) RateLimitConfig {
421
-
441
+ configs []RateLimitConfigToLoad , statsManager stats.Manager , mergeDomainConfigs bool ,
442
+ ) RateLimitConfig {
422
443
ret := & rateLimitConfigImpl {map [string ]* rateLimitDomain {}, statsManager , mergeDomainConfigs }
423
444
for _ , config := range configs {
424
445
ret .loadConfig (config )
@@ -430,8 +451,8 @@ func NewRateLimitConfigImpl(
430
451
type rateLimitConfigLoaderImpl struct {}
431
452
432
453
func (this * rateLimitConfigLoaderImpl ) Load (
433
- configs []RateLimitConfigToLoad , statsManager stats.Manager , mergeDomainConfigs bool ) RateLimitConfig {
434
-
454
+ configs []RateLimitConfigToLoad , statsManager stats.Manager , mergeDomainConfigs bool ,
455
+ ) RateLimitConfig {
435
456
return NewRateLimitConfigImpl (configs , statsManager , mergeDomainConfigs )
436
457
}
437
458
0 commit comments