Skip to content

Commit 6ffef63

Browse files
committed
Add more validation and test on instance_limits
Signed-off-by: Justin Jung <[email protected]>
1 parent 025a93a commit 6ffef63

File tree

7 files changed

+82
-8
lines changed

7 files changed

+82
-8
lines changed

pkg/configs/instance_limits.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,18 @@ func (cfg *InstanceLimits) RegisterFlagsWithPrefix(f *flag.FlagSet, prefix strin
2020
}
2121

2222
func (cfg *InstanceLimits) Validate(monitoredResources flagext.StringSliceCSV) error {
23+
if cfg.CPUUtilization > 1 || cfg.CPUUtilization < 0 {
24+
return errors.New("cpu_utilization must be between 0 and 1")
25+
}
26+
2327
if cfg.CPUUtilization > 0 && !strings.Contains(monitoredResources.String(), string(resource.CPU)) {
2428
return errors.New("monitored_resources config must include \"cpu\" as well")
2529
}
2630

31+
if cfg.HeapUtilization > 1 || cfg.HeapUtilization < 0 {
32+
return errors.New("heap_utilization must be between 0 and 1")
33+
}
34+
2735
if cfg.HeapUtilization > 0 && !strings.Contains(monitoredResources.String(), string(resource.Heap)) {
2836
return errors.New("monitored_resources config must include \"heap\" as well")
2937
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package configs
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func Test_Validate(t *testing.T) {
11+
for name, tc := range map[string]struct {
12+
instanceLimits InstanceLimits
13+
monitoredResources []string
14+
err error
15+
}{
16+
"correct config should pass validation": {
17+
instanceLimits: InstanceLimits{
18+
CPUUtilization: 0.5,
19+
HeapUtilization: 0.5,
20+
},
21+
monitoredResources: []string{"cpu", "heap"},
22+
err: nil,
23+
},
24+
"utilization config less than 0 should fail validation": {
25+
instanceLimits: InstanceLimits{
26+
CPUUtilization: -0.5,
27+
HeapUtilization: 0.5,
28+
},
29+
monitoredResources: []string{"cpu", "heap"},
30+
err: errors.New("cpu_utilization must be between 0 and 1"),
31+
},
32+
"utilization config greater than 1 should fail validation": {
33+
instanceLimits: InstanceLimits{
34+
CPUUtilization: 0.5,
35+
HeapUtilization: 1.5,
36+
},
37+
monitoredResources: []string{"cpu", "heap"},
38+
err: errors.New("heap_utilization must be between 0 and 1"),
39+
},
40+
"missing cpu in monitored_resources config should fail validation": {
41+
instanceLimits: InstanceLimits{
42+
CPUUtilization: 0.5,
43+
},
44+
monitoredResources: []string{"heap"},
45+
err: errors.New("monitored_resources config must include \"cpu\" as well"),
46+
},
47+
"missing heap in monitored_resources config should fail validation": {
48+
instanceLimits: InstanceLimits{
49+
HeapUtilization: 0.5,
50+
},
51+
monitoredResources: []string{"cpu"},
52+
err: errors.New("monitored_resources config must include \"heap\" as well"),
53+
},
54+
} {
55+
t.Run(name, func(t *testing.T) {
56+
err := tc.instanceLimits.Validate(tc.monitoredResources)
57+
if tc.err != nil {
58+
require.Errorf(t, err, tc.err.Error())
59+
} else {
60+
require.NoError(t, err)
61+
}
62+
})
63+
}
64+
}

pkg/ingester/ingester.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ func New(cfg Config, limits *validation.Overrides, registerer prometheus.Registe
790790
if cfg.DefaultLimits.HeapUtilization > 0 {
791791
resourceLimits[resource.Heap] = cfg.DefaultLimits.HeapUtilization
792792
}
793-
i.resourceBasedLimiter, err = limiter.NewResourceBasedLimiter(resourceMonitor, resourceLimits, registerer)
793+
i.resourceBasedLimiter, err = limiter.NewResourceBasedLimiter(resourceMonitor, resourceLimits, registerer, "ingester")
794794
if err != nil {
795795
return nil, errors.Wrap(err, "error creating resource based limiter")
796796
}

pkg/ingester/ingester_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3078,7 +3078,7 @@ func Test_Ingester_Query_ResourceThresholdBreached(t *testing.T) {
30783078
resource.CPU: 0.5,
30793079
resource.Heap: 0.5,
30803080
}
3081-
i.resourceBasedLimiter, err = limiter.NewResourceBasedLimiter(&mockResourceMonitor{cpu: 0.4, heap: 0.6}, limits, nil)
3081+
i.resourceBasedLimiter, err = limiter.NewResourceBasedLimiter(&mockResourceMonitor{cpu: 0.4, heap: 0.6}, limits, nil, "ingester")
30823082
require.NoError(t, err)
30833083

30843084
// Wait until it's ACTIVE

pkg/storegateway/gateway.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ func newStoreGateway(gatewayCfg Config, storageCfg cortex_tsdb.BlocksStorageConf
250250
if gatewayCfg.InstanceLimits.HeapUtilization > 0 {
251251
resourceLimits[resource.Heap] = gatewayCfg.InstanceLimits.HeapUtilization
252252
}
253-
g.resourceBasedLimiter, err = util_limiter.NewResourceBasedLimiter(resourceMonitor, resourceLimits, reg)
253+
g.resourceBasedLimiter, err = util_limiter.NewResourceBasedLimiter(resourceMonitor, resourceLimits, reg, "store-gateway")
254254
if err != nil {
255255
return nil, errors.Wrap(err, "error creating resource based limiter")
256256
}

pkg/storegateway/gateway_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ func TestStoreGateway_SeriesThrottledByResourceMonitor(t *testing.T) {
12201220
resource.CPU: 0.5,
12211221
resource.Heap: 0.5,
12221222
}
1223-
g.resourceBasedLimiter, err = util_limiter.NewResourceBasedLimiter(&mockResourceMonitor{cpu: 0.4, heap: 0.6}, limits, nil)
1223+
g.resourceBasedLimiter, err = util_limiter.NewResourceBasedLimiter(&mockResourceMonitor{cpu: 0.4, heap: 0.6}, limits, nil, "store-gateway")
12241224
require.NoError(t, err)
12251225

12261226
srv := newBucketStoreSeriesServer(setUserIDToGRPCContext(ctx, userID))

pkg/util/limiter/resource_based_limiter.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ type ResourceBasedLimiter struct {
2323
limitBreachedCount *prometheus.CounterVec
2424
}
2525

26-
func NewResourceBasedLimiter(resourceMonitor resource.IMonitor, limits map[resource.Type]float64, registerer prometheus.Registerer) (*ResourceBasedLimiter, error) {
26+
func NewResourceBasedLimiter(resourceMonitor resource.IMonitor, limits map[resource.Type]float64, registerer prometheus.Registerer, component string) (*ResourceBasedLimiter, error) {
2727
for resType, limit := range limits {
2828
switch resType {
2929
case resource.CPU, resource.Heap:
3030
promauto.With(registerer).NewGauge(prometheus.GaugeOpts{
3131
Name: "cortex_resource_based_limiter_limit",
32-
ConstLabels: map[string]string{"resource": string(resType)},
32+
Help: "Limit set for the resource utilization.",
33+
ConstLabels: map[string]string{"component": component},
3334
}).Set(limit)
3435
default:
3536
return nil, fmt.Errorf("unsupported resource type: [%s]", resType)
@@ -41,8 +42,9 @@ func NewResourceBasedLimiter(resourceMonitor resource.IMonitor, limits map[resou
4142
limits: limits,
4243
limitBreachedCount: promauto.With(registerer).NewCounterVec(
4344
prometheus.CounterOpts{
44-
Name: "cortex_resource_based_limiter_limit_breached",
45-
Help: "The total number of times resource based limiter was throttled.",
45+
Name: "cortex_resource_based_limiter_limit_breached",
46+
Help: "The total number of times resource based limiter was throttled.",
47+
ConstLabels: map[string]string{"component": component},
4648
},
4749
[]string{"resource"},
4850
),

0 commit comments

Comments
 (0)