Merge pull request #113485 from MikeSpreitzer/apf-borrowing

Add borrowing between priority levels in APF
This commit is contained in:
Kubernetes Prow Robot
2022-11-09 01:40:12 -08:00
committed by GitHub
72 changed files with 2226 additions and 459 deletions

View File

@@ -10423,6 +10423,16 @@
"format": "int32",
"type": "integer"
},
"borrowingLimitPercent": {
"description": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
"format": "int32",
"type": "integer"
},
"lendablePercent": {
"description": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"format": "int32",
"type": "integer"
},
"limitResponse": {
"$ref": "#/definitions/io.k8s.api.flowcontrol.v1beta2.LimitResponse",
"description": "`limitResponse` indicates what to do with requests that can not be executed right now"
@@ -10969,6 +10979,16 @@
"io.k8s.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration": {
"description": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?",
"properties": {
"borrowingLimitPercent": {
"description": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
"format": "int32",
"type": "integer"
},
"lendablePercent": {
"description": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"format": "int32",
"type": "integer"
},
"limitResponse": {
"$ref": "#/definitions/io.k8s.api.flowcontrol.v1beta3.LimitResponse",
"description": "`limitResponse` indicates what to do with requests that can not be executed right now"

View File

@@ -259,6 +259,16 @@
"format": "int32",
"type": "integer"
},
"borrowingLimitPercent": {
"description": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
"format": "int32",
"type": "integer"
},
"lendablePercent": {
"description": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"format": "int32",
"type": "integer"
},
"limitResponse": {
"allOf": [
{

View File

@@ -255,6 +255,16 @@
"io.k8s.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration": {
"description": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?",
"properties": {
"borrowingLimitPercent": {
"description": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
"format": "int32",
"type": "integer"
},
"lendablePercent": {
"description": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"format": "int32",
"type": "integer"
},
"limitResponse": {
"allOf": [
{

View File

@@ -176,6 +176,14 @@ func TestDefaulting(t *testing.T) {
{Group: "scheduling.k8s.io", Version: "v1alpha1", Kind: "PriorityClassList"}: {},
{Group: "scheduling.k8s.io", Version: "v1beta1", Kind: "PriorityClassList"}: {},
{Group: "scheduling.k8s.io", Version: "v1", Kind: "PriorityClassList"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Kind: "PriorityLevelConfiguration"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Kind: "PriorityLevelConfigurationList"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Kind: "PriorityLevelConfiguration"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Kind: "PriorityLevelConfigurationList"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfiguration"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfigurationList"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfiguration"}: {},
{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfigurationList"}: {},
}
f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))

View File

@@ -38,6 +38,7 @@ import (
corefuzzer "k8s.io/kubernetes/pkg/apis/core/fuzzer"
discoveryfuzzer "k8s.io/kubernetes/pkg/apis/discovery/fuzzer"
extensionsfuzzer "k8s.io/kubernetes/pkg/apis/extensions/fuzzer"
flowcontrolfuzzer "k8s.io/kubernetes/pkg/apis/flowcontrol/fuzzer"
networkingfuzzer "k8s.io/kubernetes/pkg/apis/networking/fuzzer"
policyfuzzer "k8s.io/kubernetes/pkg/apis/policy/fuzzer"
rbacfuzzer "k8s.io/kubernetes/pkg/apis/rbac/fuzzer"
@@ -107,4 +108,5 @@ var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
metafuzzer.Funcs,
schedulingfuzzer.Funcs,
discoveryfuzzer.Funcs,
flowcontrolfuzzer.Funcs,
)

View File

@@ -0,0 +1,37 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fuzzer
import (
fuzz "github.com/google/gofuzz"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/apis/flowcontrol"
)
// Funcs returns the fuzzer functions for the flowcontrol api group.
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{
func(obj *flowcontrol.LimitedPriorityLevelConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj) // fuzz self without calling this function again
if obj.LendablePercent == nil {
i := int32(0)
obj.LendablePercent = &i
}
},
}
}

View File

@@ -17,31 +17,46 @@ limitations under the License.
package internalbootstrap
import (
"fmt"
"testing"
"github.com/google/go-cmp/cmp"
flowcontrol "k8s.io/api/flowcontrol/v1beta3"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
)
func TestMandatoryAlreadyDefaulted(t *testing.T) {
func TestBootstrapConfigurationWithDefaulted(t *testing.T) {
scheme := NewAPFScheme()
for _, obj := range bootstrap.MandatoryFlowSchemas {
obj2 := obj.DeepCopyObject().(*flowcontrol.FlowSchema)
scheme.Default(obj2)
if apiequality.Semantic.DeepEqual(obj, obj2) {
t.Logf("Defaulting makes no change to %#+v", *obj)
} else {
t.Errorf("Defaulting changed %#+v to %#+v", *obj, *obj2)
}
}
for _, obj := range bootstrap.MandatoryPriorityLevelConfigurations {
obj2 := obj.DeepCopyObject().(*flowcontrol.PriorityLevelConfiguration)
scheme.Default(obj2)
if apiequality.Semantic.DeepEqual(obj, obj2) {
t.Logf("Defaulting makes no change to %#+v", *obj)
} else {
t.Errorf("Defaulting changed %#+v to %#+v", *obj, *obj2)
}
bootstrapFlowSchemas := make([]*flowcontrol.FlowSchema, 0)
bootstrapFlowSchemas = append(bootstrapFlowSchemas, bootstrap.MandatoryFlowSchemas...)
bootstrapFlowSchemas = append(bootstrapFlowSchemas, bootstrap.SuggestedFlowSchemas...)
for _, original := range bootstrapFlowSchemas {
t.Run(fmt.Sprintf("FlowSchema/%s", original.Name), func(t *testing.T) {
defaulted := original.DeepCopyObject().(*flowcontrol.FlowSchema)
scheme.Default(defaulted)
if apiequality.Semantic.DeepEqual(original, defaulted) {
t.Logf("Defaulting makes no change to FlowSchema: %q", original.Name)
return
}
t.Errorf("Expected defaulting to not change FlowSchema: %q, diff: %s", original.Name, cmp.Diff(original, defaulted))
})
}
bootstrapPriorityLevels := make([]*flowcontrol.PriorityLevelConfiguration, 0)
bootstrapPriorityLevels = append(bootstrapPriorityLevels, bootstrap.MandatoryPriorityLevelConfigurations...)
bootstrapPriorityLevels = append(bootstrapPriorityLevels, bootstrap.SuggestedPriorityLevelConfigurations...)
for _, original := range bootstrapPriorityLevels {
t.Run(fmt.Sprintf("PriorityLevelConfiguration/%s", original.Name), func(t *testing.T) {
defaulted := original.DeepCopyObject().(*flowcontrol.PriorityLevelConfiguration)
scheme.Default(defaulted)
if apiequality.Semantic.DeepEqual(original, defaulted) {
t.Logf("Defaulting makes no change to PriorityLevelConfiguration: %q", original.Name)
return
}
t.Errorf("Expected defaulting to not change PriorityLevelConfiguration: %q, diff: %s", original.Name, cmp.Diff(original, defaulted))
})
}
}

View File

@@ -416,6 +416,35 @@ type LimitedPriorityLevelConfiguration struct {
// `limitResponse` indicates what to do with requests that can not be executed right now
LimitResponse LimitResponse
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
LendablePercent *int32
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
BorrowingLimitPercent *int32
}
// LimitResponse defines how to handle requests that can not be executed right now.

View File

@@ -44,6 +44,10 @@ func SetDefaults_LimitedPriorityLevelConfiguration(lplc *v1alpha1.LimitedPriorit
if lplc.AssuredConcurrencyShares == 0 {
lplc.AssuredConcurrencyShares = PriorityLevelConfigurationDefaultAssuredConcurrencyShares
}
if lplc.LendablePercent == nil {
lplc.LendablePercent = new(int32)
*lplc.LendablePercent = 0
}
}
// SetDefaults_FlowSchema sets default values for flow schema

View File

@@ -0,0 +1,80 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
)
func TestDefaultWithPriorityLevelConfiguration(t *testing.T) {
tests := []struct {
name string
original runtime.Object
expected runtime.Object
}{
{
name: "LendablePercent is not specified, should default to zero",
original: &flowcontrolv1alpha1.PriorityLevelConfiguration{
Spec: flowcontrolv1alpha1.PriorityLevelConfigurationSpec{
Type: flowcontrolv1alpha1.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1alpha1.LimitedPriorityLevelConfiguration{
AssuredConcurrencyShares: 5,
LimitResponse: flowcontrolv1alpha1.LimitResponse{
Type: flowcontrolv1alpha1.LimitResponseTypeReject,
},
},
},
},
expected: &flowcontrolv1alpha1.PriorityLevelConfiguration{
Spec: flowcontrolv1alpha1.PriorityLevelConfigurationSpec{
Type: flowcontrolv1alpha1.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1alpha1.LimitedPriorityLevelConfiguration{
AssuredConcurrencyShares: 5,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrolv1alpha1.LimitResponse{
Type: flowcontrolv1alpha1.LimitResponseTypeReject,
},
},
},
},
},
}
scheme := runtime.NewScheme()
if err := AddToScheme(scheme); err != nil {
t.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
original := test.original
expected := test.expected
scheme.Default(original)
if !reflect.DeepEqual(expected, original) {
t.Errorf("Expected defaulting to work - diff: %s", cmp.Diff(expected, original))
}
})
}
}

View File

@@ -459,6 +459,8 @@ func autoConvert_v1alpha1_LimitedPriorityLevelConfiguration_To_flowcontrol_Limit
if err := Convert_v1alpha1_LimitResponse_To_flowcontrol_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}
@@ -467,6 +469,8 @@ func autoConvert_flowcontrol_LimitedPriorityLevelConfiguration_To_v1alpha1_Limit
if err := Convert_flowcontrol_LimitResponse_To_v1alpha1_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}

View File

@@ -44,6 +44,10 @@ func SetDefaults_LimitedPriorityLevelConfiguration(lplc *v1beta1.LimitedPriority
if lplc.AssuredConcurrencyShares == 0 {
lplc.AssuredConcurrencyShares = PriorityLevelConfigurationDefaultAssuredConcurrencyShares
}
if lplc.LendablePercent == nil {
lplc.LendablePercent = new(int32)
*lplc.LendablePercent = 0
}
}
// SetDefaults_FlowSchema sets default values for flow schema

View File

@@ -0,0 +1,80 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
)
func TestDefaultWithPriorityLevelConfiguration(t *testing.T) {
tests := []struct {
name string
original runtime.Object
expected runtime.Object
}{
{
name: "LendablePercent is not specified, should default to zero",
original: &flowcontrolv1beta1.PriorityLevelConfiguration{
Spec: flowcontrolv1beta1.PriorityLevelConfigurationSpec{
Type: flowcontrolv1beta1.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta1.LimitedPriorityLevelConfiguration{
AssuredConcurrencyShares: 5,
LimitResponse: flowcontrolv1beta1.LimitResponse{
Type: flowcontrolv1beta1.LimitResponseTypeReject,
},
},
},
},
expected: &flowcontrolv1beta1.PriorityLevelConfiguration{
Spec: flowcontrolv1beta1.PriorityLevelConfigurationSpec{
Type: flowcontrolv1beta1.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta1.LimitedPriorityLevelConfiguration{
AssuredConcurrencyShares: 5,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrolv1beta1.LimitResponse{
Type: flowcontrolv1beta1.LimitResponseTypeReject,
},
},
},
},
},
}
scheme := runtime.NewScheme()
if err := AddToScheme(scheme); err != nil {
t.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
original := test.original
expected := test.expected
scheme.Default(original)
if !reflect.DeepEqual(expected, original) {
t.Errorf("Expected defaulting to work - diff: %s", cmp.Diff(expected, original))
}
})
}
}

View File

@@ -459,6 +459,8 @@ func autoConvert_v1beta1_LimitedPriorityLevelConfiguration_To_flowcontrol_Limite
if err := Convert_v1beta1_LimitResponse_To_flowcontrol_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}
@@ -467,6 +469,8 @@ func autoConvert_flowcontrol_LimitedPriorityLevelConfiguration_To_v1beta1_Limite
if err := Convert_flowcontrol_LimitResponse_To_v1beta1_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}

View File

@@ -44,6 +44,10 @@ func SetDefaults_LimitedPriorityLevelConfiguration(lplc *v1beta2.LimitedPriority
if lplc.AssuredConcurrencyShares == 0 {
lplc.AssuredConcurrencyShares = PriorityLevelConfigurationDefaultAssuredConcurrencyShares
}
if lplc.LendablePercent == nil {
lplc.LendablePercent = new(int32)
*lplc.LendablePercent = 0
}
}
// SetDefaults_FlowSchema sets default values for flow schema

View File

@@ -0,0 +1,80 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta2
import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
)
func TestDefaultWithPriorityLevelConfiguration(t *testing.T) {
tests := []struct {
name string
original runtime.Object
expected runtime.Object
}{
{
name: "LendablePercent is not specified, should default to zero",
original: &flowcontrolv1beta2.PriorityLevelConfiguration{
Spec: flowcontrolv1beta2.PriorityLevelConfigurationSpec{
Type: flowcontrolv1beta2.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta2.LimitedPriorityLevelConfiguration{
AssuredConcurrencyShares: 5,
LimitResponse: flowcontrolv1beta2.LimitResponse{
Type: flowcontrolv1beta2.LimitResponseTypeReject,
},
},
},
},
expected: &flowcontrolv1beta2.PriorityLevelConfiguration{
Spec: flowcontrolv1beta2.PriorityLevelConfigurationSpec{
Type: flowcontrolv1beta2.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta2.LimitedPriorityLevelConfiguration{
AssuredConcurrencyShares: 5,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrolv1beta2.LimitResponse{
Type: flowcontrolv1beta2.LimitResponseTypeReject,
},
},
},
},
},
}
scheme := runtime.NewScheme()
if err := AddToScheme(scheme); err != nil {
t.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
original := test.original
expected := test.expected
scheme.Default(original)
if !reflect.DeepEqual(expected, original) {
t.Errorf("Expected defaulting to work - diff: %s", cmp.Diff(expected, original))
}
})
}
}

View File

@@ -459,6 +459,8 @@ func autoConvert_v1beta2_LimitedPriorityLevelConfiguration_To_flowcontrol_Limite
if err := Convert_v1beta2_LimitResponse_To_flowcontrol_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}
@@ -467,6 +469,8 @@ func autoConvert_flowcontrol_LimitedPriorityLevelConfiguration_To_v1beta2_Limite
if err := Convert_flowcontrol_LimitResponse_To_v1beta2_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}

View File

@@ -44,6 +44,10 @@ func SetDefaults_LimitedPriorityLevelConfiguration(lplc *v1beta3.LimitedPriority
if lplc.NominalConcurrencyShares == 0 {
lplc.NominalConcurrencyShares = PriorityLevelConfigurationDefaultNominalConcurrencyShares
}
if lplc.LendablePercent == nil {
lplc.LendablePercent = new(int32)
*lplc.LendablePercent = 0
}
}
// SetDefaults_FlowSchema sets default values for flow schema

View File

@@ -0,0 +1,80 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta3
import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
flowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
)
func TestDefaultWithPriorityLevelConfiguration(t *testing.T) {
tests := []struct {
name string
original runtime.Object
expected runtime.Object
}{
{
name: "LendablePercent is not specified, should default to zero",
original: &flowcontrolv1beta3.PriorityLevelConfiguration{
Spec: flowcontrolv1beta3.PriorityLevelConfigurationSpec{
Type: flowcontrolv1beta3.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta3.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 5,
LimitResponse: flowcontrolv1beta3.LimitResponse{
Type: flowcontrolv1beta3.LimitResponseTypeReject,
},
},
},
},
expected: &flowcontrolv1beta3.PriorityLevelConfiguration{
Spec: flowcontrolv1beta3.PriorityLevelConfigurationSpec{
Type: flowcontrolv1beta3.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta3.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 5,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrolv1beta3.LimitResponse{
Type: flowcontrolv1beta3.LimitResponseTypeReject,
},
},
},
},
},
}
scheme := runtime.NewScheme()
if err := AddToScheme(scheme); err != nil {
t.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
original := test.original
expected := test.expected
scheme.Default(original)
if !reflect.DeepEqual(expected, original) {
t.Errorf("Expected defaulting to work - diff: %s", cmp.Diff(expected, original))
}
})
}
}

View File

@@ -459,6 +459,8 @@ func autoConvert_v1beta3_LimitedPriorityLevelConfiguration_To_flowcontrol_Limite
if err := Convert_v1beta3_LimitResponse_To_flowcontrol_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}
@@ -472,6 +474,8 @@ func autoConvert_flowcontrol_LimitedPriorityLevelConfiguration_To_v1beta3_Limite
if err := Convert_flowcontrol_LimitResponse_To_v1beta3_LimitResponse(&in.LimitResponse, &out.LimitResponse, s); err != nil {
return err
}
out.LendablePercent = (*int32)(unsafe.Pointer(in.LendablePercent))
out.BorrowingLimitPercent = (*int32)(unsafe.Pointer(in.BorrowingLimitPercent))
return nil
}

View File

@@ -388,6 +388,14 @@ func ValidateLimitedPriorityLevelConfiguration(lplc *flowcontrol.LimitedPriority
allErrs = append(allErrs, field.Invalid(fldPath.Child(getVersionedFieldNameForConcurrencyShares(requestGV)), lplc.NominalConcurrencyShares, "must be positive"))
}
allErrs = append(allErrs, ValidateLimitResponse(lplc.LimitResponse, fldPath.Child("limitResponse"))...)
if lplc.LendablePercent != nil && !(*lplc.LendablePercent >= 0 && *lplc.LendablePercent <= 100) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("lendablePercent"), *lplc.LendablePercent, "must be between 0 and 100, inclusive"))
}
if lplc.BorrowingLimitPercent != nil && *lplc.BorrowingLimitPercent < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("borrowingLimitPercent"), *lplc.BorrowingLimitPercent, "if specified, must be a non-negative integer"))
}
return allErrs
}

View File

@@ -17,6 +17,7 @@ limitations under the License.
package validation
import (
"fmt"
"math"
"testing"
@@ -31,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/kubernetes/pkg/apis/flowcontrol"
"k8s.io/utils/pointer"
)
func TestFlowSchemaValidation(t *testing.T) {
@@ -1019,6 +1021,7 @@ func TestPriorityLevelConfigurationValidation(t *testing.T) {
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 5,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeReject,
}}},
@@ -1434,3 +1437,92 @@ func TestValidateLimitedPriorityLevelConfiguration(t *testing.T) {
})
}
}
func TestValidateLimitedPriorityLevelConfigurationWithBorrowing(t *testing.T) {
errLendablePercentFn := func(v int32) field.ErrorList {
return field.ErrorList{
field.Invalid(field.NewPath("spec").Child("limited").Child("lendablePercent"), v, "must be between 0 and 100, inclusive"),
}
}
errBorrowingLimitPercentFn := func(v int32) field.ErrorList {
return field.ErrorList{
field.Invalid(field.NewPath("spec").Child("limited").Child("borrowingLimitPercent"), v, "if specified, must be a non-negative integer"),
}
}
makeTestNameFn := func(lendablePercent *int32, borrowingLimitPercent *int32) string {
formatFn := func(v *int32) string {
if v == nil {
return "<nil>"
}
return fmt.Sprintf("%d", *v)
}
return fmt.Sprintf("lendablePercent %s, borrowingLimitPercent %s", formatFn(lendablePercent), formatFn(borrowingLimitPercent))
}
tests := []struct {
lendablePercent *int32
borrowingLimitPercent *int32
errExpected field.ErrorList
}{
{
lendablePercent: nil,
errExpected: nil,
},
{
lendablePercent: pointer.Int32(0),
errExpected: nil,
},
{
lendablePercent: pointer.Int32(100),
errExpected: nil,
},
{
lendablePercent: pointer.Int32(101),
errExpected: errLendablePercentFn(101),
},
{
lendablePercent: pointer.Int32(-1),
errExpected: errLendablePercentFn(-1),
},
{
borrowingLimitPercent: nil,
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(1),
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(100),
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(0),
errExpected: nil,
},
{
borrowingLimitPercent: pointer.Int32(-1),
errExpected: errBorrowingLimitPercentFn(-1),
},
}
for _, test := range tests {
t.Run(makeTestNameFn(test.lendablePercent, test.borrowingLimitPercent), func(t *testing.T) {
configuration := &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 1,
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeReject,
},
LendablePercent: test.lendablePercent,
BorrowingLimitPercent: test.borrowingLimitPercent,
}
specPath := field.NewPath("spec").Child("limited")
errGot := ValidateLimitedPriorityLevelConfiguration(configuration, flowcontrolv1beta3.SchemeGroupVersion, specPath)
if !cmp.Equal(test.errExpected, errGot) {
t.Errorf("Expected error: %v, diff: %s", test.errExpected, cmp.Diff(test.errExpected, errGot))
}
})
}
}

View File

@@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse {
func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) {
*out = *in
in.LimitResponse.DeepCopyInto(&out.LimitResponse)
if in.LendablePercent != nil {
in, out := &in.LendablePercent, &out.LendablePercent
*out = new(int32)
**out = **in
}
if in.BorrowingLimitPercent != nil {
in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent
*out = new(int32)
**out = **in
}
return
}

View File

@@ -31674,6 +31674,20 @@ func schema_k8sio_api_flowcontrol_v1alpha1_LimitedPriorityLevelConfiguration(ref
Ref: ref("k8s.io/api/flowcontrol/v1alpha1.LimitResponse"),
},
},
"lendablePercent": {
SchemaProps: spec.SchemaProps{
Description: "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
Type: []string{"integer"},
Format: "int32",
},
},
"borrowingLimitPercent": {
SchemaProps: spec.SchemaProps{
Description: "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
Type: []string{"integer"},
Format: "int32",
},
},
},
},
},
@@ -32659,6 +32673,20 @@ func schema_k8sio_api_flowcontrol_v1beta1_LimitedPriorityLevelConfiguration(ref
Ref: ref("k8s.io/api/flowcontrol/v1beta1.LimitResponse"),
},
},
"lendablePercent": {
SchemaProps: spec.SchemaProps{
Description: "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
Type: []string{"integer"},
Format: "int32",
},
},
"borrowingLimitPercent": {
SchemaProps: spec.SchemaProps{
Description: "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
Type: []string{"integer"},
Format: "int32",
},
},
},
},
},
@@ -33644,6 +33672,20 @@ func schema_k8sio_api_flowcontrol_v1beta2_LimitedPriorityLevelConfiguration(ref
Ref: ref("k8s.io/api/flowcontrol/v1beta2.LimitResponse"),
},
},
"lendablePercent": {
SchemaProps: spec.SchemaProps{
Description: "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
Type: []string{"integer"},
Format: "int32",
},
},
"borrowingLimitPercent": {
SchemaProps: spec.SchemaProps{
Description: "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
Type: []string{"integer"},
Format: "int32",
},
},
},
},
},
@@ -34631,6 +34673,20 @@ func schema_k8sio_api_flowcontrol_v1beta3_LimitedPriorityLevelConfiguration(ref
Ref: ref("k8s.io/api/flowcontrol/v1beta3.LimitResponse"),
},
},
"lendablePercent": {
SchemaProps: spec.SchemaProps{
Description: "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
Type: []string{"integer"},
Format: "int32",
},
},
"borrowingLimitPercent": {
SchemaProps: spec.SchemaProps{
Description: "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
Type: []string{"integer"},
Format: "int32",
},
},
},
},
},

View File

@@ -30,10 +30,10 @@ import (
flowcontrollisters "k8s.io/client-go/listers/flowcontrol/v1beta3"
"k8s.io/client-go/tools/cache"
flowcontrolapisv1beta3 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta3"
"k8s.io/utils/pointer"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
)
func TestEnsurePriorityLevel(t *testing.T) {
@@ -257,6 +257,7 @@ func TestPriorityLevelSpecChanged(t *testing.T) {
Type: flowcontrolv1beta3.PriorityLevelEnablementLimited,
Limited: &flowcontrolv1beta3.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: flowcontrolapisv1beta3.PriorityLevelConfigurationDefaultNominalConcurrencyShares,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrolv1beta3.LimitResponse{
Type: flowcontrolv1beta3.LimitResponseTypeReject,
},
@@ -291,7 +292,10 @@ func TestPriorityLevelSpecChanged(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
w := priorityLevelSpecChanged(testCase.expected, testCase.actual)
assert.Equal(t, testCase.specChanged, w)
if testCase.specChanged != w {
t.Errorf("Expected priorityLevelSpecChanged to return %t, but got: %t - diff: %s", testCase.specChanged, w,
cmp.Diff(testCase.expected, testCase.actual))
}
})
}
}
@@ -472,6 +476,7 @@ func (b *plBuilder) WithLimited(nominalConcurrencyShares int32) *plBuilder {
b.object.Spec.Type = flowcontrolv1beta3.PriorityLevelEnablementLimited
b.object.Spec.Limited = &flowcontrolv1beta3.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: nominalConcurrencyShares,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrolv1beta3.LimitResponse{
Type: flowcontrolv1beta3.LimitResponseTypeReject,
},

View File

@@ -689,102 +689,105 @@ func init() {
}
var fileDescriptor_45ba024d525b289b = []byte{
// 1505 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4b, 0x6f, 0xdb, 0xc6,
0x16, 0x36, 0x65, 0xc9, 0xb6, 0xc6, 0xcf, 0x8c, 0x13, 0x58, 0x70, 0x00, 0xc9, 0xe1, 0x05, 0x6e,
0x72, 0x6f, 0x12, 0x32, 0xce, 0x4d, 0x72, 0x53, 0x04, 0x45, 0x60, 0x3a, 0x69, 0x5e, 0xb6, 0x6b,
0x8f, 0x92, 0x14, 0x0d, 0x52, 0x20, 0x34, 0x35, 0x96, 0x26, 0x96, 0x48, 0x76, 0x86, 0x54, 0xea,
0x22, 0x8b, 0x02, 0xfd, 0x03, 0xfd, 0x01, 0x59, 0x76, 0xd1, 0x75, 0x7f, 0x41, 0x97, 0x46, 0xd1,
0x45, 0x96, 0x59, 0x09, 0xb1, 0xba, 0x2d, 0xba, 0x6e, 0xb3, 0x2a, 0x66, 0x38, 0x24, 0x45, 0xbd,
0xa8, 0xd4, 0x40, 0x56, 0xdd, 0x89, 0xe7, 0xf1, 0x9d, 0x39, 0x67, 0xce, 0x39, 0xf3, 0xd9, 0xe0,
0xee, 0xfe, 0x75, 0xa6, 0x11, 0x47, 0xdf, 0xf7, 0x77, 0x31, 0xb5, 0xb1, 0x87, 0x99, 0xde, 0xc4,
0x76, 0xc5, 0xa1, 0xba, 0x54, 0x98, 0x2e, 0xd1, 0xf7, 0xea, 0xce, 0x0b, 0xcb, 0xb1, 0x3d, 0xea,
0xd4, 0xf5, 0xe6, 0xaa, 0x59, 0x77, 0x6b, 0xe6, 0xaa, 0x5e, 0xc5, 0x36, 0xa6, 0xa6, 0x87, 0x2b,
0x9a, 0x4b, 0x1d, 0xcf, 0x81, 0xa5, 0xc0, 0x41, 0x33, 0x5d, 0xa2, 0x75, 0x38, 0x68, 0xa1, 0xc3,
0xf2, 0xc5, 0x2a, 0xf1, 0x6a, 0xfe, 0xae, 0x66, 0x39, 0x0d, 0xbd, 0xea, 0x54, 0x1d, 0x5d, 0xf8,
0xed, 0xfa, 0x7b, 0xe2, 0x4b, 0x7c, 0x88, 0x5f, 0x01, 0xde, 0xf2, 0x95, 0xf8, 0x00, 0x0d, 0xd3,
0xaa, 0x11, 0x1b, 0xd3, 0x03, 0xdd, 0xdd, 0xaf, 0x72, 0x01, 0xd3, 0x1b, 0xd8, 0x33, 0xf5, 0x66,
0xcf, 0x29, 0x96, 0xf5, 0x41, 0x5e, 0xd4, 0xb7, 0x3d, 0xd2, 0xc0, 0x3d, 0x0e, 0xd7, 0xd2, 0x1c,
0x98, 0x55, 0xc3, 0x0d, 0xb3, 0xdb, 0x4f, 0x7d, 0x02, 0x96, 0x3e, 0xa9, 0x3b, 0x2f, 0x6e, 0x11,
0xe6, 0x11, 0xbb, 0xea, 0x13, 0x56, 0xc3, 0x74, 0x13, 0x7b, 0x35, 0xa7, 0x02, 0x6f, 0x82, 0xac,
0x77, 0xe0, 0xe2, 0x82, 0xb2, 0xa2, 0x9c, 0xcb, 0x1b, 0xe7, 0x0f, 0x5b, 0xa5, 0xb1, 0x76, 0xab,
0x94, 0x7d, 0x78, 0xe0, 0xe2, 0x77, 0xad, 0xd2, 0xe9, 0x01, 0x6e, 0x5c, 0x8d, 0x84, 0xa3, 0xfa,
0x2a, 0x03, 0x00, 0xb7, 0x2a, 0x8b, 0xd0, 0xf0, 0x19, 0x98, 0xe2, 0xe9, 0x56, 0x4c, 0xcf, 0x14,
0x98, 0xd3, 0x97, 0x2f, 0x69, 0x71, 0xb1, 0xa3, 0x53, 0x6b, 0xee, 0x7e, 0x95, 0x0b, 0x98, 0xc6,
0xad, 0xb5, 0xe6, 0xaa, 0xf6, 0xe9, 0xee, 0x73, 0x6c, 0x79, 0x9b, 0xd8, 0x33, 0x0d, 0x28, 0x4f,
0x01, 0x62, 0x19, 0x8a, 0x50, 0xe1, 0x0e, 0xc8, 0x32, 0x17, 0x5b, 0x85, 0x8c, 0x40, 0xd7, 0xb5,
0x94, 0xab, 0xd4, 0xe2, 0xc3, 0x95, 0x5d, 0x6c, 0x19, 0x33, 0x61, 0x8a, 0xfc, 0x0b, 0x09, 0x28,
0xf8, 0x39, 0x98, 0x60, 0x9e, 0xe9, 0xf9, 0xac, 0x30, 0x2e, 0x40, 0x57, 0xdf, 0x07, 0x54, 0x38,
0x1a, 0x73, 0x12, 0x76, 0x22, 0xf8, 0x46, 0x12, 0x50, 0x7d, 0x93, 0x01, 0x8b, 0xb1, 0xf1, 0xba,
0x63, 0x57, 0x88, 0x47, 0x1c, 0x1b, 0xde, 0x48, 0xd4, 0xfd, 0x6c, 0x57, 0xdd, 0x97, 0xfa, 0xb8,
0xc4, 0x35, 0x87, 0x1f, 0x45, 0xe7, 0xcd, 0x08, 0xf7, 0x33, 0xc9, 0xe0, 0xef, 0x5a, 0xa5, 0xf9,
0xc8, 0x2d, 0x79, 0x1e, 0xd8, 0x04, 0xb0, 0x6e, 0x32, 0xef, 0x21, 0x35, 0x6d, 0x16, 0xc0, 0x92,
0x06, 0x96, 0x69, 0xff, 0x77, 0xb4, 0x9b, 0xe2, 0x1e, 0xc6, 0xb2, 0x0c, 0x09, 0x37, 0x7a, 0xd0,
0x50, 0x9f, 0x08, 0xf0, 0xdf, 0x60, 0x82, 0x62, 0x93, 0x39, 0x76, 0x21, 0x2b, 0x8e, 0x1c, 0xd5,
0x0b, 0x09, 0x29, 0x92, 0x5a, 0xf8, 0x1f, 0x30, 0xd9, 0xc0, 0x8c, 0x99, 0x55, 0x5c, 0xc8, 0x09,
0xc3, 0x79, 0x69, 0x38, 0xb9, 0x19, 0x88, 0x51, 0xa8, 0x57, 0x7f, 0x52, 0xc0, 0x5c, 0x5c, 0xa7,
0x0d, 0xc2, 0x3c, 0xf8, 0xb4, 0xa7, 0xfb, 0xb4, 0xd1, 0x72, 0xe2, 0xde, 0xa2, 0xf7, 0x16, 0x64,
0xb8, 0xa9, 0x50, 0xd2, 0xd1, 0x79, 0xdb, 0x20, 0x47, 0x3c, 0xdc, 0xe0, 0x55, 0x1f, 0x3f, 0x37,
0x7d, 0xf9, 0xfc, 0x7b, 0x74, 0x89, 0x31, 0x2b, 0x71, 0x73, 0xf7, 0x38, 0x02, 0x0a, 0x80, 0xd4,
0xdf, 0xc6, 0x3b, 0x53, 0xe0, 0x1d, 0x09, 0x7f, 0x50, 0xc0, 0xb2, 0x4b, 0x89, 0x43, 0x89, 0x77,
0xb0, 0x81, 0x9b, 0xb8, 0xbe, 0xee, 0xd8, 0x7b, 0xa4, 0xea, 0x53, 0x93, 0xd7, 0x52, 0x66, 0x75,
0x2b, 0x35, 0xf4, 0xf6, 0x40, 0x08, 0x84, 0xf7, 0x30, 0xc5, 0xb6, 0x85, 0x0d, 0x55, 0x9e, 0x69,
0x79, 0x88, 0xf1, 0x90, 0xb3, 0xc0, 0xfb, 0x00, 0x36, 0x4c, 0x8f, 0xd7, 0xb4, 0xba, 0x4d, 0xb1,
0x85, 0x2b, 0x1c, 0x55, 0xb4, 0x64, 0x2e, 0xee, 0x8f, 0xcd, 0x1e, 0x0b, 0xd4, 0xc7, 0x0b, 0x7e,
0xab, 0x80, 0xc5, 0x4a, 0xef, 0xa2, 0x91, 0x9d, 0x79, 0x7d, 0xa4, 0x52, 0xf7, 0x59, 0x54, 0xc6,
0x52, 0xbb, 0x55, 0x5a, 0xec, 0xa3, 0x40, 0xfd, 0xa2, 0xc1, 0x2f, 0x40, 0x8e, 0xfa, 0x75, 0xcc,
0x0a, 0x59, 0x71, 0xc3, 0xe9, 0x61, 0xb7, 0x9d, 0x3a, 0xb1, 0x0e, 0x10, 0xf7, 0xf9, 0x8c, 0x78,
0xb5, 0xb2, 0x2f, 0x36, 0x16, 0x8b, 0xaf, 0x5b, 0xa8, 0x50, 0x80, 0xaa, 0xbe, 0x04, 0x0b, 0xdd,
0x8b, 0x03, 0xd6, 0x00, 0xb0, 0xc2, 0x59, 0x65, 0x05, 0x45, 0xc4, 0xbd, 0xf2, 0x1e, 0x9d, 0x15,
0x0d, 0x7a, 0xbc, 0x36, 0x23, 0x11, 0x43, 0x1d, 0xd8, 0xea, 0x25, 0x30, 0x73, 0x87, 0x3a, 0xbe,
0x2b, 0x0f, 0x09, 0x57, 0x40, 0xd6, 0x36, 0x1b, 0xe1, 0x0a, 0x8a, 0xf6, 0xe2, 0x96, 0xd9, 0xc0,
0x48, 0x68, 0xd4, 0xef, 0x15, 0x30, 0xbb, 0x41, 0x1a, 0xc4, 0x43, 0x98, 0xb9, 0x8e, 0xcd, 0x30,
0xbc, 0x9a, 0x58, 0x5b, 0x67, 0xba, 0xd6, 0xd6, 0x89, 0x84, 0x71, 0xc7, 0xc2, 0x7a, 0x0a, 0x26,
0xbf, 0xf4, 0xb1, 0x4f, 0xec, 0xaa, 0x5c, 0xdb, 0x57, 0x53, 0x33, 0xdc, 0x09, 0xec, 0x13, 0x1d,
0x67, 0x4c, 0xf3, 0x45, 0x20, 0x35, 0x28, 0x84, 0x54, 0x7f, 0x57, 0xc0, 0x19, 0x11, 0x19, 0x57,
0x06, 0x77, 0x32, 0x7c, 0x0a, 0x0a, 0x26, 0x63, 0x3e, 0xc5, 0x95, 0x75, 0xc7, 0xb6, 0x7c, 0xca,
0x67, 0xe0, 0xa0, 0x5c, 0x33, 0x29, 0x66, 0x22, 0x9d, 0x9c, 0xb1, 0x22, 0xd3, 0x29, 0xac, 0x0d,
0xb0, 0x43, 0x03, 0x11, 0xe0, 0x3e, 0x98, 0xad, 0x77, 0x26, 0x2f, 0xf3, 0xd4, 0x52, 0xf3, 0x4c,
0x94, 0xcc, 0x38, 0x25, 0x8f, 0x90, 0x2c, 0x3b, 0x4a, 0x62, 0xab, 0x2f, 0xc0, 0xa9, 0x2d, 0x3e,
0xc8, 0xcc, 0xf1, 0xa9, 0x85, 0xe3, 0x1e, 0x84, 0x25, 0x90, 0x6b, 0x62, 0xba, 0x1b, 0xf4, 0x51,
0xde, 0xc8, 0xf3, 0x0e, 0x7c, 0xcc, 0x05, 0x28, 0x90, 0xc3, 0x8f, 0xc1, 0xbc, 0x1d, 0x7b, 0x3e,
0x42, 0x1b, 0xac, 0x30, 0x21, 0x4c, 0x17, 0xdb, 0xad, 0xd2, 0xfc, 0x56, 0x52, 0x85, 0xba, 0x6d,
0xd5, 0xa3, 0x0c, 0x58, 0x1a, 0xd0, 0xf2, 0xf0, 0x31, 0x98, 0x62, 0xf2, 0xb7, 0x6c, 0xe3, 0x73,
0xa9, 0xc9, 0x4b, 0xe7, 0x78, 0xeb, 0x86, 0x68, 0x28, 0xc2, 0x82, 0x2e, 0x98, 0xa5, 0xf2, 0x0c,
0x22, 0xa8, 0xdc, 0xbe, 0xff, 0x4b, 0x05, 0xef, 0xad, 0x4f, 0x5c, 0x5e, 0xd4, 0x89, 0x88, 0x92,
0x01, 0xe0, 0x4b, 0xb0, 0xd0, 0x91, 0x78, 0x10, 0x74, 0x5c, 0x04, 0xbd, 0x96, 0x1a, 0xb4, 0xef,
0xbd, 0x18, 0x05, 0x19, 0x77, 0x61, 0xab, 0x0b, 0x17, 0xf5, 0x44, 0x52, 0x7f, 0xc9, 0x80, 0x21,
0x0b, 0xf9, 0x03, 0x10, 0x2c, 0x33, 0x41, 0xb0, 0x6e, 0x1e, 0xe3, 0xa9, 0x19, 0x48, 0xb8, 0x48,
0x17, 0xe1, 0x5a, 0x3b, 0x4e, 0x90, 0xe1, 0x04, 0xec, 0x8f, 0x0c, 0xf8, 0xd7, 0x60, 0xe7, 0x98,
0x90, 0x3d, 0x48, 0x6c, 0xb6, 0xff, 0x77, 0x6d, 0xb6, 0xb3, 0x23, 0x40, 0xfc, 0x43, 0xd0, 0xba,
0x08, 0xda, 0x5b, 0x05, 0x14, 0x07, 0xd7, 0xed, 0x03, 0x10, 0xb6, 0x67, 0x49, 0xc2, 0x76, 0xe3,
0x18, 0x5d, 0x36, 0x80, 0xc0, 0xdd, 0x19, 0xd6, 0x5c, 0x11, 0xd3, 0x1a, 0xe1, 0xa9, 0x3d, 0x1c,
0x5a, 0x2b, 0xc1, 0x0c, 0x53, 0xfe, 0x64, 0x48, 0x78, 0xdf, 0xb6, 0xcd, 0xdd, 0x3a, 0x6e, 0x60,
0xdb, 0x93, 0x1d, 0x49, 0xc0, 0x64, 0x3d, 0x78, 0x22, 0xe5, 0x5c, 0x1b, 0xa3, 0xbd, 0x4c, 0xc3,
0x9e, 0xd4, 0xe0, 0x39, 0x96, 0x66, 0x28, 0xc4, 0x57, 0x5f, 0x29, 0x60, 0x25, 0x6d, 0x5c, 0xe1,
0x57, 0x7d, 0x68, 0xcf, 0x71, 0x58, 0xed, 0xe8, 0x34, 0xe8, 0x47, 0x05, 0x9c, 0xec, 0x47, 0x2e,
0xf8, 0x04, 0x70, 0x46, 0x11, 0xd1, 0x81, 0x68, 0x02, 0x76, 0x84, 0x14, 0x49, 0x2d, 0xbc, 0x00,
0xa6, 0x6a, 0xa6, 0x5d, 0x29, 0x93, 0xaf, 0x43, 0xb2, 0x1b, 0xf5, 0xe0, 0x5d, 0x29, 0x47, 0x91,
0x05, 0xbc, 0x05, 0x16, 0x84, 0xdf, 0x06, 0xb6, 0xab, 0x5e, 0x4d, 0x14, 0x4b, 0x4c, 0x73, 0x2e,
0x7e, 0x14, 0x76, 0xba, 0xf4, 0xa8, 0xc7, 0x43, 0xfd, 0x53, 0x01, 0xf0, 0xef, 0xbc, 0xf7, 0xe7,
0x41, 0xde, 0x74, 0x89, 0xa0, 0x7d, 0xc1, 0x14, 0xe4, 0x8d, 0xd9, 0x76, 0xab, 0x94, 0x5f, 0xdb,
0xbe, 0x17, 0x08, 0x51, 0xac, 0xe7, 0xc6, 0xe1, 0x43, 0x18, 0x3c, 0x78, 0xd2, 0x38, 0x0c, 0xcc,
0x50, 0xac, 0x87, 0xd7, 0xc1, 0x8c, 0x55, 0xf7, 0x99, 0x87, 0x69, 0xd9, 0x72, 0x5c, 0x2c, 0xb6,
0xc6, 0x94, 0x71, 0x52, 0xe6, 0x34, 0xb3, 0xde, 0xa1, 0x43, 0x09, 0x4b, 0xa8, 0x01, 0xc0, 0x5b,
0x9e, 0xb9, 0x26, 0x8f, 0x93, 0x13, 0x71, 0xe6, 0xf8, 0x85, 0x6d, 0x45, 0x52, 0xd4, 0x61, 0xa1,
0x3e, 0x07, 0xa7, 0xca, 0x98, 0x36, 0x89, 0x85, 0xd7, 0x2c, 0xcb, 0xf1, 0x6d, 0x2f, 0x24, 0xb0,
0x3a, 0xc8, 0x47, 0x66, 0x72, 0x2a, 0x4e, 0xc8, 0xf8, 0xf9, 0x08, 0x0b, 0xc5, 0x36, 0xd1, 0x18,
0x66, 0x06, 0x8e, 0xe1, 0xcf, 0x19, 0x30, 0x19, 0xc3, 0x67, 0xf7, 0x89, 0x5d, 0x91, 0xc8, 0xa7,
0x43, 0xeb, 0x07, 0xc4, 0xae, 0xbc, 0x6b, 0x95, 0xa6, 0xa5, 0x19, 0xff, 0x44, 0xc2, 0x10, 0xde,
0x07, 0x59, 0x9f, 0x61, 0x2a, 0x07, 0xec, 0x42, 0x6a, 0x37, 0x3f, 0x62, 0x98, 0x86, 0x0c, 0x68,
0x8a, 0x43, 0x73, 0x01, 0x12, 0x18, 0x70, 0x0b, 0xe4, 0xaa, 0xfc, 0x56, 0xe4, 0xe6, 0xbf, 0x98,
0x0a, 0xd6, 0x49, 0xed, 0x83, 0x46, 0x10, 0x12, 0x14, 0xc0, 0x40, 0x0a, 0xe6, 0x58, 0xa2, 0x88,
0xe2, 0xc2, 0x46, 0x61, 0x34, 0x7d, 0x6b, 0x6f, 0xc0, 0x76, 0xab, 0x34, 0x97, 0x54, 0xa1, 0xae,
0x08, 0xaa, 0x0e, 0xa6, 0x3b, 0x52, 0x4c, 0x5f, 0x82, 0xc6, 0xed, 0xc3, 0xa3, 0xe2, 0xd8, 0xeb,
0xa3, 0xe2, 0xd8, 0x9b, 0xa3, 0xe2, 0xd8, 0x37, 0xed, 0xa2, 0x72, 0xd8, 0x2e, 0x2a, 0xaf, 0xdb,
0x45, 0xe5, 0x4d, 0xbb, 0xa8, 0xbc, 0x6d, 0x17, 0x95, 0xef, 0x7e, 0x2d, 0x8e, 0x3d, 0x29, 0xa5,
0xfc, 0xb7, 0xef, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x84, 0x5f, 0xef, 0x28, 0x14, 0x00,
0x00,
// 1554 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0x13, 0xc7,
0x1b, 0xcf, 0x3a, 0x76, 0x12, 0x4f, 0x5e, 0x99, 0x10, 0xc5, 0xff, 0x20, 0xd9, 0x61, 0xff, 0x52,
0xa1, 0x05, 0x76, 0x09, 0x05, 0x4a, 0x85, 0x2a, 0x94, 0x0d, 0x94, 0xb7, 0x24, 0x24, 0x13, 0xa0,
0x2a, 0xa2, 0x12, 0x9b, 0xf5, 0xc4, 0x1e, 0x62, 0xef, 0x6e, 0x67, 0x76, 0x9d, 0xa6, 0xe2, 0x50,
0xa9, 0x5f, 0xa0, 0x1f, 0x80, 0x63, 0x0f, 0x3d, 0xf7, 0x13, 0xf4, 0x18, 0x55, 0x3d, 0x70, 0xe4,
0x64, 0x11, 0xf7, 0xda, 0x0f, 0xd0, 0x72, 0xa8, 0xaa, 0x99, 0x9d, 0xdd, 0xf5, 0xfa, 0x25, 0x6b,
0x1a, 0x89, 0x53, 0x6f, 0xd9, 0xe7, 0xe5, 0xf7, 0xbc, 0xcc, 0xf3, 0xe6, 0x80, 0x3b, 0xbb, 0xd7,
0x98, 0x46, 0x1c, 0x7d, 0xd7, 0xdf, 0xc6, 0xd4, 0xc6, 0x1e, 0x66, 0x7a, 0x03, 0xdb, 0x65, 0x87,
0xea, 0x92, 0x61, 0xba, 0x44, 0xdf, 0xa9, 0x39, 0x7b, 0x96, 0x63, 0x7b, 0xd4, 0xa9, 0xe9, 0x8d,
0x25, 0xb3, 0xe6, 0x56, 0xcd, 0x25, 0xbd, 0x82, 0x6d, 0x4c, 0x4d, 0x0f, 0x97, 0x35, 0x97, 0x3a,
0x9e, 0x03, 0x4b, 0x81, 0x82, 0x66, 0xba, 0x44, 0x6b, 0x53, 0xd0, 0x42, 0x85, 0x85, 0x0b, 0x15,
0xe2, 0x55, 0xfd, 0x6d, 0xcd, 0x72, 0xea, 0x7a, 0xc5, 0xa9, 0x38, 0xba, 0xd0, 0xdb, 0xf6, 0x77,
0xc4, 0x97, 0xf8, 0x10, 0x7f, 0x05, 0x78, 0x0b, 0x97, 0x63, 0x07, 0xea, 0xa6, 0x55, 0x25, 0x36,
0xa6, 0xfb, 0xba, 0xbb, 0x5b, 0xe1, 0x04, 0xa6, 0xd7, 0xb1, 0x67, 0xea, 0x8d, 0x2e, 0x2f, 0x16,
0xf4, 0x7e, 0x5a, 0xd4, 0xb7, 0x3d, 0x52, 0xc7, 0x5d, 0x0a, 0x57, 0xd3, 0x14, 0x98, 0x55, 0xc5,
0x75, 0xb3, 0x53, 0x4f, 0x7d, 0x02, 0xe6, 0x3f, 0xaf, 0x39, 0x7b, 0x37, 0x09, 0xf3, 0x88, 0x5d,
0xf1, 0x09, 0xab, 0x62, 0xba, 0x86, 0xbd, 0xaa, 0x53, 0x86, 0x37, 0x40, 0xd6, 0xdb, 0x77, 0x71,
0x41, 0x59, 0x54, 0xce, 0xe6, 0x8d, 0x73, 0x07, 0xcd, 0xd2, 0x50, 0xab, 0x59, 0xca, 0x3e, 0xdc,
0x77, 0xf1, 0xdb, 0x66, 0xe9, 0x54, 0x1f, 0x35, 0xce, 0x46, 0x42, 0x51, 0x7d, 0x99, 0x01, 0x80,
0x4b, 0x6d, 0x09, 0xd3, 0xf0, 0x19, 0x18, 0xe3, 0xe1, 0x96, 0x4d, 0xcf, 0x14, 0x98, 0xe3, 0x97,
0x2e, 0x6a, 0x71, 0xb2, 0x23, 0xaf, 0x35, 0x77, 0xb7, 0xc2, 0x09, 0x4c, 0xe3, 0xd2, 0x5a, 0x63,
0x49, 0x7b, 0xb0, 0xfd, 0x1c, 0x5b, 0xde, 0x1a, 0xf6, 0x4c, 0x03, 0x4a, 0x2f, 0x40, 0x4c, 0x43,
0x11, 0x2a, 0xdc, 0x04, 0x59, 0xe6, 0x62, 0xab, 0x90, 0x11, 0xe8, 0xba, 0x96, 0xf2, 0x94, 0x5a,
0xec, 0xdc, 0x96, 0x8b, 0x2d, 0x63, 0x22, 0x0c, 0x91, 0x7f, 0x21, 0x01, 0x05, 0xbf, 0x04, 0x23,
0xcc, 0x33, 0x3d, 0x9f, 0x15, 0x86, 0x05, 0xe8, 0xd2, 0xbb, 0x80, 0x0a, 0x45, 0x63, 0x4a, 0xc2,
0x8e, 0x04, 0xdf, 0x48, 0x02, 0xaa, 0xaf, 0x33, 0x60, 0x36, 0x16, 0x5e, 0x71, 0xec, 0x32, 0xf1,
0x88, 0x63, 0xc3, 0xeb, 0x89, 0xbc, 0x9f, 0xe9, 0xc8, 0xfb, 0x7c, 0x0f, 0x95, 0x38, 0xe7, 0xf0,
0xd3, 0xc8, 0xdf, 0x8c, 0x50, 0x3f, 0x9d, 0x34, 0xfe, 0xb6, 0x59, 0x9a, 0x8e, 0xd4, 0x92, 0xfe,
0xc0, 0x06, 0x80, 0x35, 0x93, 0x79, 0x0f, 0xa9, 0x69, 0xb3, 0x00, 0x96, 0xd4, 0xb1, 0x0c, 0xfb,
0xa3, 0xc1, 0x5e, 0x8a, 0x6b, 0x18, 0x0b, 0xd2, 0x24, 0x5c, 0xed, 0x42, 0x43, 0x3d, 0x2c, 0xc0,
0x0f, 0xc0, 0x08, 0xc5, 0x26, 0x73, 0xec, 0x42, 0x56, 0xb8, 0x1c, 0xe5, 0x0b, 0x09, 0x2a, 0x92,
0x5c, 0xf8, 0x21, 0x18, 0xad, 0x63, 0xc6, 0xcc, 0x0a, 0x2e, 0xe4, 0x84, 0xe0, 0xb4, 0x14, 0x1c,
0x5d, 0x0b, 0xc8, 0x28, 0xe4, 0xab, 0xbf, 0x28, 0x60, 0x2a, 0xce, 0xd3, 0x2a, 0x61, 0x1e, 0x7c,
0xda, 0x55, 0x7d, 0xda, 0x60, 0x31, 0x71, 0x6d, 0x51, 0x7b, 0x33, 0xd2, 0xdc, 0x58, 0x48, 0x69,
0xab, 0xbc, 0x0d, 0x90, 0x23, 0x1e, 0xae, 0xf3, 0xac, 0x0f, 0x9f, 0x1d, 0xbf, 0x74, 0xee, 0x1d,
0xaa, 0xc4, 0x98, 0x94, 0xb8, 0xb9, 0xbb, 0x1c, 0x01, 0x05, 0x40, 0xea, 0x1f, 0xc3, 0xed, 0x21,
0xf0, 0x8a, 0x84, 0x3f, 0x29, 0x60, 0xc1, 0xa5, 0xc4, 0xa1, 0xc4, 0xdb, 0x5f, 0xc5, 0x0d, 0x5c,
0x5b, 0x71, 0xec, 0x1d, 0x52, 0xf1, 0xa9, 0xc9, 0x73, 0x29, 0xa3, 0xba, 0x99, 0x6a, 0x7a, 0xa3,
0x2f, 0x04, 0xc2, 0x3b, 0x98, 0x62, 0xdb, 0xc2, 0x86, 0x2a, 0x7d, 0x5a, 0x38, 0x42, 0xf8, 0x08,
0x5f, 0xe0, 0x3d, 0x00, 0xeb, 0xa6, 0xc7, 0x73, 0x5a, 0xd9, 0xa0, 0xd8, 0xc2, 0x65, 0x8e, 0x2a,
0x4a, 0x32, 0x17, 0xd7, 0xc7, 0x5a, 0x97, 0x04, 0xea, 0xa1, 0x05, 0xbf, 0x57, 0xc0, 0x6c, 0xb9,
0x7b, 0xd0, 0xc8, 0xca, 0xbc, 0x36, 0x50, 0xaa, 0x7b, 0x0c, 0x2a, 0x63, 0xbe, 0xd5, 0x2c, 0xcd,
0xf6, 0x60, 0xa0, 0x5e, 0xd6, 0xe0, 0x57, 0x20, 0x47, 0xfd, 0x1a, 0x66, 0x85, 0xac, 0x78, 0xe1,
0x74, 0xb3, 0x1b, 0x4e, 0x8d, 0x58, 0xfb, 0x88, 0xeb, 0x7c, 0x41, 0xbc, 0xea, 0x96, 0x2f, 0x26,
0x16, 0x8b, 0x9f, 0x5b, 0xb0, 0x50, 0x80, 0xaa, 0xbe, 0x00, 0x33, 0x9d, 0x83, 0x03, 0x56, 0x01,
0xb0, 0xc2, 0x5e, 0x65, 0x05, 0x45, 0xd8, 0xbd, 0xfc, 0x0e, 0x95, 0x15, 0x35, 0x7a, 0x3c, 0x36,
0x23, 0x12, 0x43, 0x6d, 0xd8, 0xea, 0x45, 0x30, 0x71, 0x9b, 0x3a, 0xbe, 0x2b, 0x9d, 0x84, 0x8b,
0x20, 0x6b, 0x9b, 0xf5, 0x70, 0x04, 0x45, 0x73, 0x71, 0xdd, 0xac, 0x63, 0x24, 0x38, 0xea, 0x8f,
0x0a, 0x98, 0x5c, 0x25, 0x75, 0xe2, 0x21, 0xcc, 0x5c, 0xc7, 0x66, 0x18, 0x5e, 0x49, 0x8c, 0xad,
0xd3, 0x1d, 0x63, 0xeb, 0x44, 0x42, 0xb8, 0x6d, 0x60, 0x3d, 0x05, 0xa3, 0x5f, 0xfb, 0xd8, 0x27,
0x76, 0x45, 0x8e, 0xed, 0x2b, 0xa9, 0x11, 0x6e, 0x06, 0xf2, 0x89, 0x8a, 0x33, 0xc6, 0xf9, 0x20,
0x90, 0x1c, 0x14, 0x42, 0xaa, 0x7f, 0x67, 0xc0, 0x69, 0x61, 0x19, 0x97, 0xfb, 0x57, 0x32, 0x7c,
0x0a, 0x0a, 0x26, 0x63, 0x3e, 0xc5, 0xe5, 0x15, 0xc7, 0xb6, 0x7c, 0xca, 0x7b, 0x60, 0x7f, 0xab,
0x6a, 0x52, 0xcc, 0x44, 0x38, 0x39, 0x63, 0x51, 0x86, 0x53, 0x58, 0xee, 0x23, 0x87, 0xfa, 0x22,
0xc0, 0x5d, 0x30, 0x59, 0x6b, 0x0f, 0x5e, 0xc6, 0xa9, 0xa5, 0xc6, 0x99, 0x48, 0x99, 0x31, 0x27,
0x5d, 0x48, 0xa6, 0x1d, 0x25, 0xb1, 0xe1, 0x67, 0x60, 0xba, 0x86, 0xed, 0xb2, 0xb9, 0x5d, 0xc3,
0x1b, 0x98, 0x5a, 0xd8, 0xf6, 0x44, 0x9f, 0xe4, 0x8c, 0xd9, 0x56, 0xb3, 0x34, 0xbd, 0x9a, 0x64,
0xa1, 0x4e, 0x59, 0xf8, 0x00, 0xcc, 0x6d, 0x3b, 0x94, 0x3a, 0x7b, 0xc4, 0xae, 0x08, 0x3b, 0x21,
0x48, 0x56, 0x80, 0xfc, 0xaf, 0xd5, 0x2c, 0xcd, 0x19, 0xbd, 0x04, 0x50, 0x6f, 0x3d, 0x75, 0x0f,
0xcc, 0xad, 0xf3, 0xc1, 0xc2, 0x1c, 0x9f, 0x5a, 0x38, 0xee, 0x09, 0x58, 0x02, 0xb9, 0x06, 0xa6,
0xdb, 0x41, 0x5d, 0xe7, 0x8d, 0x3c, 0xef, 0x88, 0xc7, 0x9c, 0x80, 0x02, 0x3a, 0x8f, 0xc4, 0x8e,
0x35, 0x1f, 0xa1, 0x55, 0x56, 0x18, 0x11, 0xa2, 0x22, 0x92, 0xf5, 0x24, 0x0b, 0x75, 0xca, 0xaa,
0x87, 0x19, 0x30, 0xdf, 0xa7, 0x05, 0xe1, 0x63, 0x30, 0xc6, 0xe4, 0xdf, 0xb2, 0xad, 0xce, 0xa6,
0x3e, 0x86, 0x54, 0x8e, 0xb7, 0x40, 0x88, 0x86, 0x22, 0x2c, 0xe8, 0x82, 0x49, 0x2a, 0x7d, 0x10,
0x46, 0xe5, 0x36, 0xf8, 0x38, 0x15, 0xbc, 0x3b, 0x3f, 0xf1, 0x73, 0xa3, 0x76, 0x44, 0x94, 0x34,
0x00, 0x5f, 0x80, 0x99, 0xb6, 0xc0, 0x03, 0xa3, 0xc3, 0xc2, 0xe8, 0xd5, 0x54, 0xa3, 0x3d, 0xdf,
0xc5, 0x28, 0x48, 0xbb, 0x33, 0xeb, 0x1d, 0xb8, 0xa8, 0xcb, 0x92, 0xfa, 0x5b, 0x06, 0x1c, 0xb1,
0x20, 0xde, 0xc3, 0xc1, 0x67, 0x26, 0x0e, 0xbe, 0x1b, 0xc7, 0x58, 0x7d, 0x7d, 0x0f, 0x40, 0xd2,
0x71, 0x00, 0x2e, 0x1f, 0xc7, 0xc8, 0xd1, 0x07, 0xe1, 0x9f, 0x19, 0xf0, 0xff, 0xfe, 0xca, 0xf1,
0x81, 0x78, 0x3f, 0x31, 0x69, 0x3f, 0xe9, 0x98, 0xb4, 0x67, 0x06, 0x80, 0xf8, 0xef, 0x60, 0xec,
0x38, 0x18, 0xdf, 0x28, 0xa0, 0xd8, 0x3f, 0x6f, 0xef, 0xe1, 0x80, 0x7c, 0x96, 0x3c, 0x20, 0xaf,
0x1f, 0xa3, 0xca, 0xfa, 0x1c, 0x94, 0xb7, 0x8f, 0x2a, 0xae, 0xe8, 0xf2, 0x1b, 0x60, 0xf5, 0x1f,
0x1c, 0x99, 0x2b, 0x71, 0xa9, 0xa6, 0xfc, 0x84, 0x49, 0x68, 0xdf, 0xb2, 0xf9, 0x02, 0xaa, 0xf3,
0x1d, 0x12, 0x54, 0x24, 0x01, 0xa3, 0xb5, 0x60, 0x65, 0xcb, 0xbe, 0x36, 0x06, 0xdb, 0x94, 0x47,
0xad, 0xf8, 0xe0, 0x3c, 0x90, 0x62, 0x28, 0xc4, 0x57, 0x5f, 0x2a, 0x60, 0x31, 0xad, 0x5d, 0xe1,
0x37, 0x3d, 0xce, 0xb0, 0xe3, 0x5c, 0xd9, 0x83, 0x9f, 0x65, 0x3f, 0x2b, 0xe0, 0x64, 0xaf, 0x63,
0x87, 0x77, 0x00, 0xbf, 0x70, 0xa2, 0xf3, 0x24, 0xea, 0x80, 0x4d, 0x41, 0x45, 0x92, 0x0b, 0xcf,
0x83, 0xb1, 0xaa, 0x69, 0x97, 0xb7, 0xc8, 0xb7, 0xe1, 0xf1, 0x1d, 0xd5, 0xe0, 0x1d, 0x49, 0x47,
0x91, 0x04, 0xbc, 0x09, 0x66, 0x84, 0xde, 0x2a, 0xb6, 0x2b, 0x5e, 0x55, 0x24, 0x4b, 0x1e, 0x0f,
0xd1, 0x52, 0xd8, 0xec, 0xe0, 0xa3, 0x2e, 0x0d, 0xf5, 0x2f, 0x05, 0xc0, 0x7f, 0xb3, 0xef, 0xcf,
0x81, 0xbc, 0xe9, 0x12, 0x71, 0x86, 0x06, 0x5d, 0x90, 0x37, 0x26, 0x5b, 0xcd, 0x52, 0x7e, 0x79,
0xe3, 0x6e, 0x40, 0x44, 0x31, 0x9f, 0x0b, 0x87, 0x8b, 0x30, 0x58, 0x78, 0x52, 0x38, 0x34, 0xcc,
0x50, 0xcc, 0x87, 0xd7, 0xc0, 0x84, 0x55, 0xf3, 0x99, 0x87, 0xe9, 0x96, 0xe5, 0xb8, 0x58, 0x4c,
0x8d, 0x31, 0xe3, 0xa4, 0x8c, 0x69, 0x62, 0xa5, 0x8d, 0x87, 0x12, 0x92, 0x50, 0x03, 0x80, 0x97,
0x3c, 0x73, 0x4d, 0x6e, 0x27, 0x27, 0xec, 0x4c, 0xf1, 0x07, 0x5b, 0x8f, 0xa8, 0xa8, 0x4d, 0x42,
0x7d, 0x0e, 0xe6, 0xb6, 0x30, 0x6d, 0x10, 0x0b, 0x2f, 0x5b, 0x96, 0xe3, 0xdb, 0x5e, 0x78, 0x50,
0xeb, 0x20, 0x1f, 0x89, 0xc9, 0xae, 0x38, 0x21, 0xed, 0xe7, 0x23, 0x2c, 0x14, 0xcb, 0x44, 0x6d,
0x98, 0xe9, 0xdb, 0x86, 0xbf, 0x66, 0xc0, 0x68, 0x0c, 0x9f, 0xdd, 0x25, 0x76, 0x59, 0x22, 0x9f,
0x0a, 0xa5, 0xef, 0x13, 0xbb, 0xfc, 0xb6, 0x59, 0x1a, 0x97, 0x62, 0xfc, 0x13, 0x09, 0x41, 0x78,
0x0f, 0x64, 0x7d, 0x86, 0xa9, 0x6c, 0xb0, 0xf3, 0xa9, 0xd5, 0xfc, 0x88, 0x61, 0x1a, 0x5e, 0x40,
0x63, 0x1c, 0x9a, 0x13, 0x90, 0xc0, 0x80, 0xeb, 0x20, 0x57, 0xe1, 0xaf, 0x22, 0x27, 0xff, 0x85,
0x54, 0xb0, 0xf6, 0x9f, 0x1a, 0x41, 0x21, 0x08, 0x0a, 0x0a, 0x60, 0x20, 0x05, 0x53, 0x2c, 0x91,
0x44, 0xf1, 0x60, 0x83, 0x5c, 0x34, 0x3d, 0x73, 0x6f, 0xc0, 0x56, 0xb3, 0x34, 0x95, 0x64, 0xa1,
0x0e, 0x0b, 0xaa, 0x0e, 0xc6, 0xdb, 0x42, 0x4c, 0x1f, 0x82, 0xc6, 0xad, 0x83, 0xc3, 0xe2, 0xd0,
0xab, 0xc3, 0xe2, 0xd0, 0xeb, 0xc3, 0xe2, 0xd0, 0x77, 0xad, 0xa2, 0x72, 0xd0, 0x2a, 0x2a, 0xaf,
0x5a, 0x45, 0xe5, 0x75, 0xab, 0xa8, 0xbc, 0x69, 0x15, 0x95, 0x1f, 0x7e, 0x2f, 0x0e, 0x3d, 0x29,
0xa5, 0xfc, 0xf7, 0xf1, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x2e, 0x29, 0x16, 0xb8, 0x14,
0x00, 0x00,
}
func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) {
@@ -1155,6 +1158,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i
_ = i
var l int
_ = l
if m.BorrowingLimitPercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent))
i--
dAtA[i] = 0x20
}
if m.LendablePercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent))
i--
dAtA[i] = 0x18
}
{
size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -1904,6 +1917,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) {
n += 1 + sovGenerated(uint64(m.AssuredConcurrencyShares))
l = m.LimitResponse.Size()
n += 1 + l + sovGenerated(uint64(l))
if m.LendablePercent != nil {
n += 1 + sovGenerated(uint64(*m.LendablePercent))
}
if m.BorrowingLimitPercent != nil {
n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent))
}
return n
}
@@ -2259,6 +2278,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string {
s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`,
`AssuredConcurrencyShares:` + fmt.Sprintf("%v", this.AssuredConcurrencyShares) + `,`,
`LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`,
`LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`,
`BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`,
`}`,
}, "")
return s
@@ -3543,6 +3564,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.LendablePercent = &v
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.BorrowingLimitPercent = &v
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])

View File

@@ -176,6 +176,35 @@ message LimitedPriorityLevelConfiguration {
// `limitResponse` indicates what to do with requests that can not be executed right now
optional LimitResponse limitResponse = 2;
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
optional int32 lendablePercent = 3;
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
optional int32 borrowingLimitPercent = 4;
}
// NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the

View File

@@ -438,6 +438,35 @@ type LimitedPriorityLevelConfiguration struct {
// `limitResponse` indicates what to do with requests that can not be executed right now
LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"`
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"`
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"`
}
// LimitResponse defines how to handle requests that can not be executed right now.

View File

@@ -114,6 +114,8 @@ var map_LimitedPriorityLevelConfiguration = map[string]string{
"": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?",
"assuredConcurrencyShares": "`assuredConcurrencyShares` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) ",
"limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now",
"lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
}
func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string {

View File

@@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse {
func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) {
*out = *in
in.LimitResponse.DeepCopyInto(&out.LimitResponse)
if in.LendablePercent != nil {
in, out := &in.LendablePercent, &out.LendablePercent
*out = new(int32)
**out = **in
}
if in.BorrowingLimitPercent != nil {
in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent
*out = new(int32)
**out = **in
}
return
}

View File

@@ -689,101 +689,105 @@ func init() {
}
var fileDescriptor_80171c2a4e3669de = []byte{
// 1496 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcb, 0x73, 0xdb, 0x44,
0x18, 0x8f, 0x1c, 0x3b, 0x89, 0xbf, 0x3c, 0xbb, 0x69, 0x27, 0x9e, 0x74, 0xc6, 0x4e, 0xc5, 0x0c,
0x05, 0xda, 0xca, 0x6d, 0x69, 0x69, 0x81, 0xe1, 0x11, 0xa5, 0x50, 0x4a, 0x93, 0x34, 0xdd, 0xb4,
0xc0, 0x94, 0xce, 0x50, 0x59, 0xde, 0xd8, 0x6a, 0x6c, 0x49, 0xd5, 0xae, 0x9c, 0x09, 0xbd, 0x30,
0xfc, 0x05, 0x9c, 0xe1, 0xc8, 0x81, 0x3b, 0xff, 0x00, 0x47, 0x3a, 0x9c, 0x7a, 0xec, 0xc9, 0x50,
0x73, 0xe2, 0xc0, 0x1d, 0x7a, 0x62, 0x76, 0xb5, 0x92, 0x2c, 0xbf, 0xe4, 0x69, 0x67, 0x7a, 0xe2,
0x66, 0x7d, 0x8f, 0xdf, 0xf7, 0xd8, 0xdf, 0x7e, 0xfb, 0x25, 0x70, 0x75, 0xff, 0x32, 0xd5, 0x2c,
0xa7, 0xbc, 0xef, 0x57, 0x88, 0x67, 0x13, 0x46, 0x68, 0xb9, 0x45, 0xec, 0xaa, 0xe3, 0x95, 0xa5,
0xc2, 0x70, 0xad, 0xf2, 0x5e, 0xc3, 0x39, 0x30, 0x1d, 0x9b, 0x79, 0x4e, 0xa3, 0xdc, 0x3a, 0x57,
0x21, 0xcc, 0x38, 0x57, 0xae, 0x11, 0x9b, 0x78, 0x06, 0x23, 0x55, 0xcd, 0xf5, 0x1c, 0xe6, 0xa0,
0x62, 0x60, 0xaf, 0x19, 0xae, 0xa5, 0x75, 0xd9, 0x6b, 0xd2, 0x7e, 0xf5, 0x4c, 0xcd, 0x62, 0x75,
0xbf, 0xa2, 0x99, 0x4e, 0xb3, 0x5c, 0x73, 0x6a, 0x4e, 0x59, 0xb8, 0x55, 0xfc, 0x3d, 0xf1, 0x25,
0x3e, 0xc4, 0xaf, 0x00, 0x6e, 0xf5, 0x42, 0x1c, 0xbe, 0x69, 0x98, 0x75, 0xcb, 0x26, 0xde, 0x61,
0xd9, 0xdd, 0xaf, 0x71, 0x01, 0x2d, 0x37, 0x09, 0x33, 0xca, 0xad, 0xbe, 0x24, 0x56, 0xcb, 0xc3,
0xbc, 0x3c, 0xdf, 0x66, 0x56, 0x93, 0xf4, 0x39, 0xbc, 0x95, 0xe6, 0x40, 0xcd, 0x3a, 0x69, 0x1a,
0xbd, 0x7e, 0xea, 0x1d, 0x58, 0xf9, 0xb8, 0xe1, 0x1c, 0x5c, 0xb1, 0x28, 0xb3, 0xec, 0x9a, 0x6f,
0xd1, 0x3a, 0xf1, 0xb6, 0x08, 0xab, 0x3b, 0x55, 0xf4, 0x01, 0x64, 0xd9, 0xa1, 0x4b, 0x0a, 0xca,
0x9a, 0xf2, 0x5a, 0x5e, 0x3f, 0xf5, 0xa8, 0x5d, 0x9a, 0xe8, 0xb4, 0x4b, 0xd9, 0x5b, 0x87, 0x2e,
0x79, 0xd6, 0x2e, 0x1d, 0x1f, 0xe2, 0xc6, 0xd5, 0x58, 0x38, 0xaa, 0xdf, 0x67, 0x00, 0xb8, 0xd5,
0xae, 0x08, 0x8d, 0xee, 0xc1, 0x0c, 0x2f, 0xb7, 0x6a, 0x30, 0x43, 0x60, 0xce, 0x9e, 0x3f, 0xab,
0xc5, 0xbd, 0x8e, 0xb2, 0xd6, 0xdc, 0xfd, 0x1a, 0x17, 0x50, 0x8d, 0x5b, 0x6b, 0xad, 0x73, 0xda,
0x8d, 0xca, 0x7d, 0x62, 0xb2, 0x2d, 0xc2, 0x0c, 0x1d, 0xc9, 0x2c, 0x20, 0x96, 0xe1, 0x08, 0x15,
0xed, 0x40, 0x96, 0xba, 0xc4, 0x2c, 0x64, 0x04, 0xba, 0xa6, 0x8d, 0x3e, 0x49, 0x2d, 0xce, 0x6d,
0xd7, 0x25, 0xa6, 0x3e, 0x17, 0x56, 0xc8, 0xbf, 0xb0, 0x40, 0x42, 0x5f, 0xc0, 0x14, 0x65, 0x06,
0xf3, 0x69, 0x61, 0xb2, 0x2f, 0xe3, 0x34, 0x4c, 0xe1, 0xa7, 0x2f, 0x48, 0xd4, 0xa9, 0xe0, 0x1b,
0x4b, 0x3c, 0xf5, 0x49, 0x06, 0x96, 0x63, 0xe3, 0x0d, 0xc7, 0xae, 0x5a, 0xcc, 0x72, 0x6c, 0xf4,
0x6e, 0xa2, 0xeb, 0x27, 0x7b, 0xba, 0xbe, 0x32, 0xc0, 0x25, 0xee, 0x38, 0x7a, 0x3b, 0x4a, 0x37,
0x23, 0xdc, 0x4f, 0x24, 0x83, 0x3f, 0x6b, 0x97, 0x16, 0x23, 0xb7, 0x64, 0x3e, 0xa8, 0x05, 0xa8,
0x61, 0x50, 0x76, 0xcb, 0x33, 0x6c, 0x1a, 0xc0, 0x5a, 0x4d, 0x22, 0xab, 0x7e, 0x63, 0xbc, 0x73,
0xe2, 0x1e, 0xfa, 0xaa, 0x0c, 0x89, 0x36, 0xfb, 0xd0, 0xf0, 0x80, 0x08, 0xe8, 0x55, 0x98, 0xf2,
0x88, 0x41, 0x1d, 0xbb, 0x90, 0x15, 0x29, 0x47, 0xfd, 0xc2, 0x42, 0x8a, 0xa5, 0x16, 0xbd, 0x0e,
0xd3, 0x4d, 0x42, 0xa9, 0x51, 0x23, 0x85, 0x9c, 0x30, 0x5c, 0x94, 0x86, 0xd3, 0x5b, 0x81, 0x18,
0x87, 0x7a, 0xf5, 0x17, 0x05, 0x16, 0xe2, 0x3e, 0x6d, 0x5a, 0x94, 0xa1, 0xbb, 0x7d, 0xdc, 0xd3,
0xc6, 0xab, 0x89, 0x7b, 0x0b, 0xe6, 0x2d, 0xc9, 0x70, 0x33, 0xa1, 0xa4, 0x8b, 0x77, 0x37, 0x20,
0x67, 0x31, 0xd2, 0xe4, 0x5d, 0x9f, 0xec, 0x69, 0x57, 0x0a, 0x49, 0xf4, 0x79, 0x09, 0x9b, 0xbb,
0xc6, 0x01, 0x70, 0x80, 0xa3, 0xfe, 0x35, 0xd9, 0x5d, 0x01, 0xe7, 0x23, 0xfa, 0x49, 0x81, 0x55,
0xd7, 0xb3, 0x1c, 0xcf, 0x62, 0x87, 0x9b, 0xa4, 0x45, 0x1a, 0x1b, 0x8e, 0xbd, 0x67, 0xd5, 0x7c,
0xcf, 0xe0, 0xad, 0x94, 0x45, 0x6d, 0xa4, 0x45, 0xde, 0x19, 0x8a, 0x80, 0xc9, 0x1e, 0xf1, 0x88,
0x6d, 0x12, 0x5d, 0x95, 0x29, 0xad, 0x8e, 0x30, 0x1e, 0x91, 0x0a, 0xfa, 0x14, 0x50, 0xd3, 0x60,
0xbc, 0xa3, 0xb5, 0x1d, 0x8f, 0x98, 0xa4, 0xca, 0x51, 0x05, 0x21, 0x73, 0x31, 0x3b, 0xb6, 0xfa,
0x2c, 0xf0, 0x00, 0x2f, 0xf4, 0xad, 0x02, 0xcb, 0xd5, 0xfe, 0x21, 0x23, 0x79, 0x79, 0x69, 0x9c,
0x46, 0x0f, 0x98, 0x51, 0xfa, 0x4a, 0xa7, 0x5d, 0x5a, 0x1e, 0xa0, 0xc0, 0x83, 0x82, 0xa1, 0xbb,
0x90, 0xf3, 0xfc, 0x06, 0xa1, 0x85, 0xac, 0x38, 0xde, 0xd4, 0xa8, 0x3b, 0x4e, 0xc3, 0x32, 0x0f,
0x31, 0x77, 0xf9, 0xdc, 0x62, 0xf5, 0x5d, 0x5f, 0xcc, 0x2a, 0x1a, 0x9f, 0xb5, 0x50, 0xe1, 0x00,
0x54, 0x7d, 0x08, 0x4b, 0xbd, 0x43, 0x03, 0xd5, 0x00, 0xcc, 0xf0, 0x9e, 0xd2, 0x82, 0x22, 0xc2,
0xbe, 0x39, 0x3e, 0xab, 0xa2, 0x3b, 0x1e, 0xcf, 0xcb, 0x48, 0x44, 0x71, 0x17, 0xb4, 0x7a, 0x16,
0xe6, 0xae, 0x7a, 0x8e, 0xef, 0xca, 0x1c, 0xd1, 0x1a, 0x64, 0x6d, 0xa3, 0x19, 0x4e, 0x9f, 0x68,
0x22, 0x6e, 0x1b, 0x4d, 0x82, 0x85, 0x46, 0xfd, 0x51, 0x81, 0xf9, 0x4d, 0xab, 0x69, 0x31, 0x4c,
0xa8, 0xeb, 0xd8, 0x94, 0xa0, 0x8b, 0x89, 0x89, 0x75, 0xa2, 0x67, 0x62, 0x1d, 0x49, 0x18, 0x77,
0xcd, 0xaa, 0x2f, 0x61, 0xfa, 0x81, 0x4f, 0x7c, 0xcb, 0xae, 0xc9, 0x79, 0x7d, 0x21, 0xad, 0xc0,
0x9b, 0x81, 0x79, 0x82, 0x6d, 0xfa, 0x2c, 0x1f, 0x01, 0x52, 0x83, 0x43, 0x44, 0xf5, 0x6f, 0x05,
0x4e, 0x88, 0xc0, 0xa4, 0x3a, 0x9c, 0xc5, 0xe8, 0x2e, 0x14, 0x0c, 0x4a, 0x7d, 0x8f, 0x54, 0x37,
0x1c, 0xdb, 0xf4, 0x3d, 0xce, 0xff, 0xc3, 0xdd, 0xba, 0xe1, 0x11, 0x2a, 0xaa, 0xc9, 0xe9, 0x6b,
0xb2, 0x9a, 0xc2, 0xfa, 0x10, 0x3b, 0x3c, 0x14, 0x01, 0xdd, 0x87, 0xf9, 0x46, 0x77, 0xed, 0xb2,
0xcc, 0x33, 0x69, 0x65, 0x26, 0x1a, 0xa6, 0x1f, 0x93, 0x19, 0x24, 0x9b, 0x8e, 0x93, 0xd0, 0xea,
0x01, 0x1c, 0xdb, 0xe6, 0x77, 0x98, 0x3a, 0xbe, 0x67, 0x92, 0x98, 0x80, 0xa8, 0x04, 0xb9, 0x16,
0xf1, 0x2a, 0x01, 0x89, 0xf2, 0x7a, 0x9e, 0xd3, 0xef, 0x33, 0x2e, 0xc0, 0x81, 0x1c, 0xbd, 0x07,
0x8b, 0x76, 0xec, 0x79, 0x1b, 0x6f, 0xd2, 0xc2, 0x94, 0x30, 0x5d, 0xee, 0xb4, 0x4b, 0x8b, 0xdb,
0x49, 0x15, 0xee, 0xb5, 0x55, 0xdb, 0x19, 0x58, 0x19, 0xc2, 0x77, 0x74, 0x1b, 0x66, 0xa8, 0xfc,
0x2d, 0x39, 0x7c, 0x32, 0xad, 0x76, 0xe9, 0x1b, 0x4f, 0xdb, 0x10, 0x0c, 0x47, 0x50, 0xc8, 0x81,
0x79, 0x4f, 0xa6, 0x20, 0x62, 0xca, 0xa9, 0x7b, 0x3e, 0x0d, 0xbb, 0xbf, 0x3b, 0x71, 0x73, 0x71,
0x37, 0x20, 0x4e, 0xe2, 0xa3, 0x87, 0xb0, 0xd4, 0x55, 0x76, 0x10, 0x73, 0x52, 0xc4, 0xbc, 0x98,
0x16, 0x73, 0xe0, 0xa1, 0xe8, 0x05, 0x19, 0x76, 0x69, 0xbb, 0x07, 0x16, 0xf7, 0x05, 0x52, 0x7f,
0xcb, 0xc0, 0x88, 0x41, 0xfc, 0x12, 0x96, 0xaa, 0x7b, 0x89, 0xa5, 0xea, 0xfd, 0xe7, 0x7f, 0x61,
0x86, 0x2e, 0x59, 0xf5, 0x9e, 0x25, 0xeb, 0xc3, 0x17, 0x88, 0x31, 0x7a, 0xe9, 0xfa, 0x27, 0x03,
0xaf, 0x0c, 0x77, 0x8e, 0x97, 0xb0, 0xeb, 0x89, 0x91, 0x76, 0xa9, 0x67, 0xa4, 0x9d, 0x1c, 0x03,
0xe2, 0xff, 0xa5, 0xac, 0x67, 0x29, 0xfb, 0x5d, 0x81, 0xe2, 0xf0, 0xbe, 0xbd, 0x84, 0x25, 0xed,
0xab, 0xe4, 0x92, 0xf6, 0xce, 0xf3, 0x93, 0x6c, 0xc8, 0xd2, 0x76, 0x75, 0x14, 0xb7, 0xa2, 0xf5,
0x6a, 0x8c, 0x27, 0xf6, 0xd7, 0x91, 0xad, 0x12, 0xdb, 0x60, 0xca, 0x5f, 0x09, 0x09, 0xef, 0x8f,
0x6c, 0xa3, 0xd2, 0x20, 0x4d, 0x62, 0x33, 0x49, 0xc8, 0x3a, 0x4c, 0x37, 0x82, 0xb7, 0x51, 0x5e,
0xea, 0xf5, 0xb1, 0x9e, 0xa4, 0x51, 0x4f, 0x69, 0xf0, 0x0c, 0x4b, 0x33, 0x1c, 0xc2, 0xab, 0x3f,
0x28, 0xb0, 0x96, 0x76, 0x59, 0xd1, 0xc1, 0x80, 0x65, 0xe7, 0x05, 0x16, 0xd9, 0xf1, 0x97, 0x9f,
0x9f, 0x15, 0x38, 0x3a, 0x68, 0xa7, 0xe0, 0xf4, 0xe7, 0x8b, 0x44, 0xb4, 0x05, 0x44, 0xf4, 0xbf,
0x29, 0xa4, 0x58, 0x6a, 0xd1, 0x69, 0x98, 0xa9, 0x1b, 0x76, 0x75, 0xd7, 0xfa, 0x3a, 0xdc, 0x6f,
0x23, 0x02, 0x7e, 0x22, 0xe5, 0x38, 0xb2, 0x40, 0x57, 0x60, 0x49, 0xf8, 0x6d, 0x12, 0xbb, 0xc6,
0xea, 0xa2, 0x57, 0xe2, 0x2a, 0xe7, 0xe2, 0xf7, 0xe0, 0x66, 0x8f, 0x1e, 0xf7, 0x79, 0xa8, 0xff,
0x2a, 0x80, 0x9e, 0xe7, 0x9d, 0x3f, 0x05, 0x79, 0xc3, 0xb5, 0xc4, 0xb2, 0x17, 0x5c, 0x81, 0xbc,
0x3e, 0xdf, 0x69, 0x97, 0xf2, 0xeb, 0x3b, 0xd7, 0x02, 0x21, 0x8e, 0xf5, 0xdc, 0x38, 0x7c, 0x02,
0x83, 0xa7, 0x4e, 0x1a, 0x87, 0x81, 0x29, 0x8e, 0xf5, 0xe8, 0x32, 0xcc, 0x99, 0x0d, 0x9f, 0x32,
0xe2, 0xed, 0x9a, 0x8e, 0x4b, 0xc4, 0xc8, 0x98, 0xd1, 0x8f, 0xca, 0x9a, 0xe6, 0x36, 0xba, 0x74,
0x38, 0x61, 0x89, 0x34, 0x00, 0x4e, 0x78, 0xea, 0x1a, 0x3c, 0x4e, 0x4e, 0xc4, 0x59, 0xe0, 0x07,
0xb6, 0x1d, 0x49, 0x71, 0x97, 0x85, 0x7a, 0x1f, 0x8e, 0xed, 0x12, 0xaf, 0x65, 0x99, 0x64, 0xdd,
0x34, 0x1d, 0xdf, 0x66, 0xe1, 0xda, 0x5a, 0x86, 0x7c, 0x64, 0x26, 0xef, 0xc4, 0x11, 0x19, 0x3f,
0x1f, 0x61, 0xe1, 0xd8, 0x26, 0xba, 0x84, 0x99, 0xe1, 0x97, 0x30, 0x03, 0xd3, 0x31, 0x7c, 0x76,
0xdf, 0xb2, 0xab, 0x12, 0xf9, 0x78, 0x68, 0x7d, 0xdd, 0xb2, 0xab, 0xcf, 0xda, 0xa5, 0x59, 0x69,
0xc6, 0x3f, 0xb1, 0x30, 0x44, 0xd7, 0x20, 0xeb, 0x53, 0xe2, 0xc9, 0xeb, 0x75, 0x2a, 0x8d, 0xcc,
0xb7, 0x29, 0xf1, 0xc2, 0xcd, 0x67, 0x86, 0x23, 0x73, 0x01, 0x16, 0x10, 0x68, 0x0b, 0x72, 0x35,
0x7e, 0x28, 0x72, 0xea, 0x9f, 0x4e, 0xc3, 0xea, 0x5e, 0xe7, 0x03, 0x1a, 0x08, 0x09, 0x0e, 0x50,
0xd0, 0x03, 0x58, 0xa0, 0x89, 0x16, 0x8a, 0xe3, 0x1a, 0x63, 0x93, 0x19, 0xd8, 0x78, 0x1d, 0x75,
0xda, 0xa5, 0x85, 0xa4, 0x0a, 0xf7, 0x04, 0x50, 0xcb, 0x30, 0xdb, 0x55, 0x60, 0xfa, 0xfc, 0xd3,
0xaf, 0x3c, 0x7a, 0x5a, 0x9c, 0x78, 0xfc, 0xb4, 0x38, 0xf1, 0xe4, 0x69, 0x71, 0xe2, 0x9b, 0x4e,
0x51, 0x79, 0xd4, 0x29, 0x2a, 0x8f, 0x3b, 0x45, 0xe5, 0x49, 0xa7, 0xa8, 0xfc, 0xd1, 0x29, 0x2a,
0xdf, 0xfd, 0x59, 0x9c, 0xb8, 0x53, 0x1c, 0xfd, 0x7f, 0xbd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff,
0x27, 0x1b, 0xb7, 0xd8, 0x11, 0x14, 0x00, 0x00,
// 1553 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4f, 0x6f, 0xdb, 0xc6,
0x12, 0x37, 0x65, 0xc9, 0xb6, 0xc6, 0x7f, 0xb3, 0x8e, 0x61, 0x3d, 0x07, 0x90, 0x1c, 0x3e, 0xe0,
0xe5, 0xbd, 0x97, 0x84, 0x4a, 0xd2, 0xa4, 0x49, 0x5b, 0xf4, 0x8f, 0xe9, 0xb4, 0x69, 0x1a, 0xdb,
0x71, 0xd6, 0x49, 0x5b, 0xa4, 0x01, 0x1a, 0x8a, 0x5a, 0x4b, 0x8c, 0x25, 0x92, 0xd9, 0x25, 0x65,
0xb8, 0xb9, 0x14, 0xfd, 0x04, 0x3d, 0xb7, 0xc7, 0x1e, 0x7a, 0xef, 0x17, 0xe8, 0xb1, 0x41, 0x4f,
0x39, 0xe6, 0xa4, 0x36, 0xea, 0xa9, 0xdf, 0xa0, 0x0d, 0x50, 0xa0, 0xd8, 0xe5, 0x92, 0x14, 0xf5,
0x8f, 0x42, 0x02, 0xe4, 0xd4, 0x9b, 0x39, 0xf3, 0x9b, 0xdf, 0xec, 0xcc, 0xce, 0xcc, 0x8e, 0x0c,
0xd7, 0x0e, 0xae, 0x30, 0xcd, 0x72, 0xca, 0x07, 0x7e, 0x85, 0x50, 0x9b, 0x78, 0x84, 0x95, 0x5b,
0xc4, 0xae, 0x3a, 0xb4, 0x2c, 0x15, 0x86, 0x6b, 0x95, 0xf7, 0x1b, 0xce, 0xa1, 0xe9, 0xd8, 0x1e,
0x75, 0x1a, 0xe5, 0xd6, 0xf9, 0x0a, 0xf1, 0x8c, 0xf3, 0xe5, 0x1a, 0xb1, 0x09, 0x35, 0x3c, 0x52,
0xd5, 0x5c, 0xea, 0x78, 0x0e, 0x2a, 0x06, 0x78, 0xcd, 0x70, 0x2d, 0xad, 0x0b, 0xaf, 0x49, 0xfc,
0xda, 0xd9, 0x9a, 0xe5, 0xd5, 0xfd, 0x8a, 0x66, 0x3a, 0xcd, 0x72, 0xcd, 0xa9, 0x39, 0x65, 0x61,
0x56, 0xf1, 0xf7, 0xc5, 0x97, 0xf8, 0x10, 0x7f, 0x05, 0x74, 0x6b, 0x17, 0x63, 0xf7, 0x4d, 0xc3,
0xac, 0x5b, 0x36, 0xa1, 0x47, 0x65, 0xf7, 0xa0, 0xc6, 0x05, 0xac, 0xdc, 0x24, 0x9e, 0x51, 0x6e,
0xf5, 0x1d, 0x62, 0xad, 0x3c, 0xcc, 0x8a, 0xfa, 0xb6, 0x67, 0x35, 0x49, 0x9f, 0xc1, 0xeb, 0x69,
0x06, 0xcc, 0xac, 0x93, 0xa6, 0xd1, 0x6b, 0xa7, 0xde, 0x85, 0xd5, 0x0f, 0x1a, 0xce, 0xe1, 0x55,
0x8b, 0x79, 0x96, 0x5d, 0xf3, 0x2d, 0x56, 0x27, 0x74, 0x9b, 0x78, 0x75, 0xa7, 0x8a, 0xde, 0x85,
0xac, 0x77, 0xe4, 0x92, 0x82, 0xb2, 0xae, 0xfc, 0x37, 0xaf, 0x9f, 0x7e, 0xdc, 0x2e, 0x4d, 0x74,
0xda, 0xa5, 0xec, 0xed, 0x23, 0x97, 0x3c, 0x6f, 0x97, 0x4e, 0x0c, 0x31, 0xe3, 0x6a, 0x2c, 0x0c,
0xd5, 0x6f, 0x32, 0x00, 0x1c, 0xb5, 0x27, 0x5c, 0xa3, 0xfb, 0x30, 0xc3, 0xc3, 0xad, 0x1a, 0x9e,
0x21, 0x38, 0x67, 0x2f, 0x9c, 0xd3, 0xe2, 0x5c, 0x47, 0xa7, 0xd6, 0xdc, 0x83, 0x1a, 0x17, 0x30,
0x8d, 0xa3, 0xb5, 0xd6, 0x79, 0xed, 0x66, 0xe5, 0x01, 0x31, 0xbd, 0x6d, 0xe2, 0x19, 0x3a, 0x92,
0xa7, 0x80, 0x58, 0x86, 0x23, 0x56, 0xb4, 0x0b, 0x59, 0xe6, 0x12, 0xb3, 0x90, 0x11, 0xec, 0x9a,
0x36, 0xfa, 0x26, 0xb5, 0xf8, 0x6c, 0x7b, 0x2e, 0x31, 0xf5, 0xb9, 0x30, 0x42, 0xfe, 0x85, 0x05,
0x13, 0xfa, 0x14, 0xa6, 0x98, 0x67, 0x78, 0x3e, 0x2b, 0x4c, 0xf6, 0x9d, 0x38, 0x8d, 0x53, 0xd8,
0xe9, 0x0b, 0x92, 0x75, 0x2a, 0xf8, 0xc6, 0x92, 0x4f, 0x7d, 0x9a, 0x81, 0xe5, 0x18, 0xbc, 0xe9,
0xd8, 0x55, 0xcb, 0xb3, 0x1c, 0x1b, 0xbd, 0x95, 0xc8, 0xfa, 0xa9, 0x9e, 0xac, 0xaf, 0x0e, 0x30,
0x89, 0x33, 0x8e, 0xde, 0x88, 0x8e, 0x9b, 0x11, 0xe6, 0x27, 0x93, 0xce, 0x9f, 0xb7, 0x4b, 0x8b,
0x91, 0x59, 0xf2, 0x3c, 0xa8, 0x05, 0xa8, 0x61, 0x30, 0xef, 0x36, 0x35, 0x6c, 0x16, 0xd0, 0x5a,
0x4d, 0x22, 0xa3, 0xfe, 0xff, 0x78, 0xf7, 0xc4, 0x2d, 0xf4, 0x35, 0xe9, 0x12, 0x6d, 0xf5, 0xb1,
0xe1, 0x01, 0x1e, 0xd0, 0x7f, 0x60, 0x8a, 0x12, 0x83, 0x39, 0x76, 0x21, 0x2b, 0x8e, 0x1c, 0xe5,
0x0b, 0x0b, 0x29, 0x96, 0x5a, 0xf4, 0x3f, 0x98, 0x6e, 0x12, 0xc6, 0x8c, 0x1a, 0x29, 0xe4, 0x04,
0x70, 0x51, 0x02, 0xa7, 0xb7, 0x03, 0x31, 0x0e, 0xf5, 0xea, 0x8f, 0x0a, 0x2c, 0xc4, 0x79, 0xda,
0xb2, 0x98, 0x87, 0xee, 0xf5, 0xd5, 0x9e, 0x36, 0x5e, 0x4c, 0xdc, 0x5a, 0x54, 0xde, 0x92, 0x74,
0x37, 0x13, 0x4a, 0xba, 0xea, 0xee, 0x26, 0xe4, 0x2c, 0x8f, 0x34, 0x79, 0xd6, 0x27, 0x7b, 0xd2,
0x95, 0x52, 0x24, 0xfa, 0xbc, 0xa4, 0xcd, 0x5d, 0xe7, 0x04, 0x38, 0xe0, 0x51, 0x7f, 0x9f, 0xec,
0x8e, 0x80, 0xd7, 0x23, 0xfa, 0x5e, 0x81, 0x35, 0x97, 0x5a, 0x0e, 0xb5, 0xbc, 0xa3, 0x2d, 0xd2,
0x22, 0x8d, 0x4d, 0xc7, 0xde, 0xb7, 0x6a, 0x3e, 0x35, 0x78, 0x2a, 0x65, 0x50, 0x9b, 0x69, 0x9e,
0x77, 0x87, 0x32, 0x60, 0xb2, 0x4f, 0x28, 0xb1, 0x4d, 0xa2, 0xab, 0xf2, 0x48, 0x6b, 0x23, 0xc0,
0x23, 0x8e, 0x82, 0x3e, 0x02, 0xd4, 0x34, 0x3c, 0x9e, 0xd1, 0xda, 0x2e, 0x25, 0x26, 0xa9, 0x72,
0x56, 0x51, 0x90, 0xb9, 0xb8, 0x3a, 0xb6, 0xfb, 0x10, 0x78, 0x80, 0x15, 0xfa, 0x4a, 0x81, 0xe5,
0x6a, 0xff, 0x90, 0x91, 0x75, 0x79, 0x79, 0x9c, 0x44, 0x0f, 0x98, 0x51, 0xfa, 0x6a, 0xa7, 0x5d,
0x5a, 0x1e, 0xa0, 0xc0, 0x83, 0x9c, 0xa1, 0x7b, 0x90, 0xa3, 0x7e, 0x83, 0xb0, 0x42, 0x56, 0x5c,
0x6f, 0xaa, 0xd7, 0x5d, 0xa7, 0x61, 0x99, 0x47, 0x98, 0x9b, 0x7c, 0x62, 0x79, 0xf5, 0x3d, 0x5f,
0xcc, 0x2a, 0x16, 0xdf, 0xb5, 0x50, 0xe1, 0x80, 0x54, 0x7d, 0x04, 0x4b, 0xbd, 0x43, 0x03, 0xd5,
0x00, 0xcc, 0xb0, 0x4f, 0x59, 0x41, 0x11, 0x6e, 0x5f, 0x1b, 0xbf, 0xaa, 0xa2, 0x1e, 0x8f, 0xe7,
0x65, 0x24, 0x62, 0xb8, 0x8b, 0x5a, 0x3d, 0x07, 0x73, 0xd7, 0xa8, 0xe3, 0xbb, 0xf2, 0x8c, 0x68,
0x1d, 0xb2, 0xb6, 0xd1, 0x0c, 0xa7, 0x4f, 0x34, 0x11, 0x77, 0x8c, 0x26, 0xc1, 0x42, 0xa3, 0x7e,
0xa7, 0xc0, 0xfc, 0x96, 0xd5, 0xb4, 0x3c, 0x4c, 0x98, 0xeb, 0xd8, 0x8c, 0xa0, 0x4b, 0x89, 0x89,
0x75, 0xb2, 0x67, 0x62, 0x1d, 0x4b, 0x80, 0xbb, 0x66, 0xd5, 0x67, 0x30, 0xfd, 0xd0, 0x27, 0xbe,
0x65, 0xd7, 0xe4, 0xbc, 0xbe, 0x98, 0x16, 0xe0, 0xad, 0x00, 0x9e, 0xa8, 0x36, 0x7d, 0x96, 0x8f,
0x00, 0xa9, 0xc1, 0x21, 0xa3, 0xfa, 0x57, 0x06, 0x4e, 0x0a, 0xc7, 0xa4, 0x3a, 0xbc, 0x8a, 0xd1,
0x3d, 0x28, 0x18, 0x8c, 0xf9, 0x94, 0x54, 0x37, 0x1d, 0xdb, 0xf4, 0x29, 0xaf, 0xff, 0xa3, 0xbd,
0xba, 0x41, 0x09, 0x13, 0xd1, 0xe4, 0xf4, 0x75, 0x19, 0x4d, 0x61, 0x63, 0x08, 0x0e, 0x0f, 0x65,
0x40, 0x0f, 0x60, 0xbe, 0xd1, 0x1d, 0xbb, 0x0c, 0xf3, 0x6c, 0x5a, 0x98, 0x89, 0x84, 0xe9, 0x2b,
0xf2, 0x04, 0xc9, 0xa4, 0xe3, 0x24, 0x35, 0x7a, 0x1b, 0x16, 0x1b, 0xc4, 0xae, 0x1a, 0x95, 0x06,
0xd9, 0x25, 0xd4, 0x24, 0xb6, 0x27, 0x5a, 0x24, 0xa7, 0x2f, 0x77, 0xda, 0xa5, 0xc5, 0xad, 0xa4,
0x0a, 0xf7, 0x62, 0xd1, 0x4d, 0x58, 0xa9, 0x38, 0x94, 0x3a, 0x87, 0x96, 0x5d, 0x13, 0x7e, 0x42,
0x92, 0xac, 0x20, 0xf9, 0x57, 0xa7, 0x5d, 0x5a, 0xd1, 0x07, 0x01, 0xf0, 0x60, 0x3b, 0xf5, 0x10,
0x56, 0x76, 0xf8, 0x4c, 0x61, 0x8e, 0x4f, 0x4d, 0x12, 0x37, 0x04, 0x2a, 0x41, 0xae, 0x45, 0x68,
0x25, 0x28, 0xea, 0xbc, 0x9e, 0xe7, 0xed, 0xf0, 0x31, 0x17, 0xe0, 0x40, 0xce, 0x23, 0xb1, 0x63,
0xcb, 0x3b, 0x78, 0x8b, 0x15, 0xa6, 0x04, 0x54, 0x44, 0xb2, 0x93, 0x54, 0xe1, 0x5e, 0xac, 0xda,
0xce, 0xc0, 0xea, 0x90, 0xfe, 0x43, 0x77, 0x60, 0x86, 0xc9, 0xbf, 0x65, 0x4f, 0x9d, 0x4a, 0xbb,
0x0b, 0x69, 0x1b, 0x4f, 0xff, 0x90, 0x0c, 0x47, 0x54, 0xc8, 0x81, 0x79, 0x2a, 0x8f, 0x20, 0x7c,
0xca, 0x57, 0xe0, 0x42, 0x1a, 0x77, 0x7f, 0x76, 0xe2, 0xcb, 0xc6, 0xdd, 0x84, 0x38, 0xc9, 0x8f,
0x1e, 0xc1, 0x52, 0x57, 0xd8, 0x81, 0xcf, 0x49, 0xe1, 0xf3, 0x52, 0x9a, 0xcf, 0x81, 0x97, 0xa2,
0x17, 0xa4, 0xdb, 0xa5, 0x9d, 0x1e, 0x5a, 0xdc, 0xe7, 0x48, 0xfd, 0x39, 0x03, 0x23, 0x1e, 0x86,
0x57, 0xb0, 0xe4, 0xdd, 0x4f, 0x2c, 0x79, 0xef, 0xbc, 0xf8, 0x8b, 0x37, 0x74, 0xe9, 0xab, 0xf7,
0x2c, 0x7d, 0xef, 0xbd, 0x84, 0x8f, 0xd1, 0x4b, 0xe0, 0x1f, 0x19, 0xf8, 0xf7, 0x70, 0xe3, 0x78,
0x29, 0xbc, 0x91, 0x18, 0xb1, 0x97, 0x7b, 0x46, 0xec, 0xa9, 0x31, 0x28, 0xfe, 0x59, 0x12, 0x7b,
0x96, 0xc4, 0x5f, 0x14, 0x28, 0x0e, 0xcf, 0xdb, 0x2b, 0x58, 0x1a, 0x3f, 0x4f, 0x2e, 0x8d, 0x6f,
0xbe, 0x78, 0x91, 0x0d, 0x59, 0x22, 0xaf, 0x8d, 0xaa, 0xad, 0x68, 0xdd, 0x1b, 0xe3, 0xc9, 0xff,
0x69, 0x64, 0xaa, 0xc4, 0x76, 0x9a, 0xf2, 0xab, 0x25, 0x61, 0xfd, 0xbe, 0xcd, 0x9f, 0x9e, 0x26,
0x7f, 0x3d, 0x82, 0x82, 0xac, 0xc3, 0x74, 0x23, 0x78, 0xab, 0x65, 0x53, 0x6f, 0x8c, 0xf5, 0x44,
0x8e, 0x7a, 0xda, 0x83, 0xb5, 0x40, 0xc2, 0x70, 0x48, 0xaf, 0x7e, 0xab, 0xc0, 0x7a, 0x5a, 0xb3,
0xa2, 0xc3, 0x01, 0xcb, 0xd7, 0x4b, 0x2c, 0xd6, 0xe3, 0x2f, 0x63, 0x3f, 0x28, 0x70, 0x7c, 0xd0,
0x8e, 0xc3, 0xcb, 0x9f, 0x2f, 0x36, 0xd1, 0x56, 0x12, 0x95, 0xff, 0x2d, 0x21, 0xc5, 0x52, 0x8b,
0xce, 0xc0, 0x4c, 0xdd, 0xb0, 0xab, 0x7b, 0xd6, 0x17, 0xe1, 0xbe, 0x1d, 0x15, 0xe0, 0x87, 0x52,
0x8e, 0x23, 0x04, 0xba, 0x0a, 0x4b, 0xc2, 0x6e, 0x8b, 0xd8, 0x35, 0xaf, 0x2e, 0x72, 0x25, 0x97,
0x86, 0xe8, 0x3d, 0xb8, 0xd5, 0xa3, 0xc7, 0x7d, 0x16, 0xea, 0x9f, 0x0a, 0xa0, 0x17, 0x79, 0xe7,
0x4f, 0x43, 0xde, 0x70, 0x2d, 0xb1, 0x7c, 0x06, 0x2d, 0x90, 0xd7, 0xe7, 0x3b, 0xed, 0x52, 0x7e,
0x63, 0xf7, 0x7a, 0x20, 0xc4, 0xb1, 0x9e, 0x83, 0xc3, 0x27, 0x30, 0x78, 0xea, 0x24, 0x38, 0x74,
0xcc, 0x70, 0xac, 0x47, 0x57, 0x60, 0xce, 0x6c, 0xf8, 0xcc, 0x23, 0x74, 0xcf, 0x74, 0x5c, 0x22,
0x46, 0xc6, 0x8c, 0x7e, 0x5c, 0xc6, 0x34, 0xb7, 0xd9, 0xa5, 0xc3, 0x09, 0x24, 0xd2, 0x00, 0x78,
0xc1, 0x33, 0xd7, 0xe0, 0x7e, 0x72, 0xc2, 0xcf, 0x02, 0xbf, 0xb0, 0x9d, 0x48, 0x8a, 0xbb, 0x10,
0xea, 0x03, 0x58, 0xd9, 0x23, 0xb4, 0x65, 0x99, 0x64, 0xc3, 0x34, 0x1d, 0xdf, 0xf6, 0xc2, 0x35,
0xba, 0x0c, 0xf9, 0x08, 0x26, 0x7b, 0xe2, 0x98, 0xf4, 0x9f, 0x8f, 0xb8, 0x70, 0x8c, 0x89, 0x9a,
0x30, 0x33, 0xbc, 0x09, 0x33, 0x30, 0x1d, 0xd3, 0x67, 0x0f, 0x2c, 0xbb, 0x2a, 0x99, 0x4f, 0x84,
0xe8, 0x1b, 0x96, 0x5d, 0x7d, 0xde, 0x2e, 0xcd, 0x4a, 0x18, 0xff, 0xc4, 0x02, 0x88, 0xae, 0x43,
0xd6, 0x67, 0x84, 0xca, 0xf6, 0x3a, 0x9d, 0x56, 0xcc, 0x77, 0x18, 0xa1, 0xe1, 0xe6, 0x33, 0xc3,
0x99, 0xb9, 0x00, 0x0b, 0x0a, 0xb4, 0x0d, 0xb9, 0x1a, 0xbf, 0x14, 0x39, 0xf5, 0xcf, 0xa4, 0x71,
0x75, 0xff, 0xbc, 0x08, 0xca, 0x40, 0x48, 0x70, 0xc0, 0x82, 0x1e, 0xc2, 0x02, 0x4b, 0xa4, 0x50,
0x5c, 0xd7, 0x18, 0x9b, 0xcc, 0xc0, 0xc4, 0xeb, 0xa8, 0xd3, 0x2e, 0x2d, 0x24, 0x55, 0xb8, 0xc7,
0x81, 0x5a, 0x86, 0xd9, 0xae, 0x00, 0xd3, 0xe7, 0x9f, 0x7e, 0xf5, 0xf1, 0xb3, 0xe2, 0xc4, 0x93,
0x67, 0xc5, 0x89, 0xa7, 0xcf, 0x8a, 0x13, 0x5f, 0x76, 0x8a, 0xca, 0xe3, 0x4e, 0x51, 0x79, 0xd2,
0x29, 0x2a, 0x4f, 0x3b, 0x45, 0xe5, 0xd7, 0x4e, 0x51, 0xf9, 0xfa, 0xb7, 0xe2, 0xc4, 0xdd, 0xe2,
0xe8, 0xff, 0x33, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x6d, 0x6e, 0x75, 0xa1, 0x14, 0x00,
0x00,
}
func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) {
@@ -1154,6 +1158,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i
_ = i
var l int
_ = l
if m.BorrowingLimitPercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent))
i--
dAtA[i] = 0x20
}
if m.LendablePercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent))
i--
dAtA[i] = 0x18
}
{
size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -1903,6 +1917,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) {
n += 1 + sovGenerated(uint64(m.AssuredConcurrencyShares))
l = m.LimitResponse.Size()
n += 1 + l + sovGenerated(uint64(l))
if m.LendablePercent != nil {
n += 1 + sovGenerated(uint64(*m.LendablePercent))
}
if m.BorrowingLimitPercent != nil {
n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent))
}
return n
}
@@ -2258,6 +2278,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string {
s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`,
`AssuredConcurrencyShares:` + fmt.Sprintf("%v", this.AssuredConcurrencyShares) + `,`,
`LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`,
`LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`,
`BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`,
`}`,
}, "")
return s
@@ -3542,6 +3564,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.LendablePercent = &v
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.BorrowingLimitPercent = &v
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])

View File

@@ -176,6 +176,35 @@ message LimitedPriorityLevelConfiguration {
// `limitResponse` indicates what to do with requests that can not be executed right now
optional LimitResponse limitResponse = 2;
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
optional int32 lendablePercent = 3;
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
optional int32 borrowingLimitPercent = 4;
}
// NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the

View File

@@ -474,6 +474,35 @@ type LimitedPriorityLevelConfiguration struct {
// `limitResponse` indicates what to do with requests that can not be executed right now
LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"`
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"`
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"`
}
// LimitResponse defines how to handle requests that can not be executed right now.

View File

@@ -114,6 +114,8 @@ var map_LimitedPriorityLevelConfiguration = map[string]string{
"": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?",
"assuredConcurrencyShares": "`assuredConcurrencyShares` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) ",
"limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now",
"lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
}
func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string {

View File

@@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse {
func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) {
*out = *in
in.LimitResponse.DeepCopyInto(&out.LimitResponse)
if in.LendablePercent != nil {
in, out := &in.LendablePercent, &out.LendablePercent
*out = new(int32)
**out = **in
}
if in.BorrowingLimitPercent != nil {
in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent
*out = new(int32)
**out = **in
}
return
}

View File

@@ -689,101 +689,105 @@ func init() {
}
var fileDescriptor_ed300aa8e672704e = []byte{
// 1497 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcb, 0x73, 0xdb, 0x44,
0x18, 0x8f, 0x1c, 0x3b, 0x89, 0xbf, 0x3c, 0xbb, 0x69, 0x27, 0x9e, 0x74, 0xc6, 0x4e, 0xc5, 0x0c,
0x05, 0xda, 0xca, 0x6d, 0x69, 0x69, 0x81, 0xe1, 0x11, 0xa5, 0x50, 0x4a, 0x93, 0x34, 0xdd, 0xb4,
0xc0, 0x94, 0xce, 0x50, 0x59, 0xde, 0xd8, 0x6a, 0x6c, 0x49, 0xd5, 0xae, 0x9c, 0x09, 0xbd, 0x30,
0xfc, 0x05, 0x9c, 0xe1, 0xc8, 0x81, 0x3b, 0xff, 0x00, 0x47, 0x3a, 0x9c, 0x7a, 0xec, 0xc9, 0x50,
0x73, 0xe2, 0xc0, 0x1d, 0x7a, 0x62, 0x76, 0xb5, 0x92, 0x2c, 0xbf, 0xe4, 0x69, 0x67, 0x7a, 0xe2,
0x66, 0x7d, 0x8f, 0xdf, 0xf7, 0xd8, 0xdf, 0x7e, 0xfb, 0x25, 0x70, 0x75, 0xff, 0x32, 0xd5, 0x2c,
0xa7, 0xbc, 0xef, 0x57, 0x88, 0x67, 0x13, 0x46, 0x68, 0xb9, 0x45, 0xec, 0xaa, 0xe3, 0x95, 0xa5,
0xc2, 0x70, 0xad, 0xf2, 0x5e, 0xc3, 0x39, 0x30, 0x1d, 0x9b, 0x79, 0x4e, 0xa3, 0xdc, 0x3a, 0x57,
0x21, 0xcc, 0x38, 0x5f, 0xae, 0x11, 0x9b, 0x78, 0x06, 0x23, 0x55, 0xcd, 0xf5, 0x1c, 0xe6, 0xa0,
0x62, 0x60, 0xaf, 0x19, 0xae, 0xa5, 0x75, 0xd9, 0x6b, 0xd2, 0x7e, 0xf5, 0x4c, 0xcd, 0x62, 0x75,
0xbf, 0xa2, 0x99, 0x4e, 0xb3, 0x5c, 0x73, 0x6a, 0x4e, 0x59, 0xb8, 0x55, 0xfc, 0x3d, 0xf1, 0x25,
0x3e, 0xc4, 0xaf, 0x00, 0x6e, 0xf5, 0x42, 0x1c, 0xbe, 0x69, 0x98, 0x75, 0xcb, 0x26, 0xde, 0x61,
0xd9, 0xdd, 0xaf, 0x71, 0x01, 0x2d, 0x37, 0x09, 0x33, 0xca, 0xad, 0x73, 0xbd, 0x49, 0xac, 0x96,
0x87, 0x79, 0x79, 0xbe, 0xcd, 0xac, 0x26, 0xe9, 0x73, 0x78, 0x2b, 0xcd, 0x81, 0x9a, 0x75, 0xd2,
0x34, 0x7a, 0xfd, 0xd4, 0x3b, 0xb0, 0xf2, 0x71, 0xc3, 0x39, 0xb8, 0x62, 0x51, 0x66, 0xd9, 0x35,
0xdf, 0xa2, 0x75, 0xe2, 0x6d, 0x11, 0x56, 0x77, 0xaa, 0xe8, 0x03, 0xc8, 0xb2, 0x43, 0x97, 0x14,
0x94, 0x35, 0xe5, 0xb5, 0xbc, 0x7e, 0xea, 0x51, 0xbb, 0x34, 0xd1, 0x69, 0x97, 0xb2, 0xb7, 0x0e,
0x5d, 0xf2, 0xac, 0x5d, 0x3a, 0x3e, 0xc4, 0x8d, 0xab, 0xb1, 0x70, 0x54, 0xbf, 0xcf, 0x00, 0x70,
0xab, 0x5d, 0x11, 0x1a, 0xdd, 0x83, 0x19, 0x5e, 0x6e, 0xd5, 0x60, 0x86, 0xc0, 0x9c, 0x3d, 0x7f,
0x56, 0x8b, 0x7b, 0x1d, 0x65, 0xad, 0xb9, 0xfb, 0x35, 0x2e, 0xa0, 0x1a, 0xb7, 0xd6, 0x5a, 0xe7,
0xb4, 0x1b, 0x95, 0xfb, 0xc4, 0x64, 0x5b, 0x84, 0x19, 0x3a, 0x92, 0x59, 0x40, 0x2c, 0xc3, 0x11,
0x2a, 0xda, 0x81, 0x2c, 0x75, 0x89, 0x59, 0xc8, 0x08, 0x74, 0x4d, 0x1b, 0x7d, 0x92, 0x5a, 0x9c,
0xdb, 0xae, 0x4b, 0x4c, 0x7d, 0x2e, 0xac, 0x90, 0x7f, 0x61, 0x81, 0x84, 0xbe, 0x80, 0x29, 0xca,
0x0c, 0xe6, 0xd3, 0xc2, 0x64, 0x5f, 0xc6, 0x69, 0x98, 0xc2, 0x4f, 0x5f, 0x90, 0xa8, 0x53, 0xc1,
0x37, 0x96, 0x78, 0xea, 0x93, 0x0c, 0x2c, 0xc7, 0xc6, 0x1b, 0x8e, 0x5d, 0xb5, 0x98, 0xe5, 0xd8,
0xe8, 0xdd, 0x44, 0xd7, 0x4f, 0xf6, 0x74, 0x7d, 0x65, 0x80, 0x4b, 0xdc, 0x71, 0xf4, 0x76, 0x94,
0x6e, 0x46, 0xb8, 0x9f, 0x48, 0x06, 0x7f, 0xd6, 0x2e, 0x2d, 0x46, 0x6e, 0xc9, 0x7c, 0x50, 0x0b,
0x50, 0xc3, 0xa0, 0xec, 0x96, 0x67, 0xd8, 0x34, 0x80, 0xb5, 0x9a, 0x44, 0x56, 0xfd, 0xc6, 0x78,
0xe7, 0xc4, 0x3d, 0xf4, 0x55, 0x19, 0x12, 0x6d, 0xf6, 0xa1, 0xe1, 0x01, 0x11, 0xd0, 0xab, 0x30,
0xe5, 0x11, 0x83, 0x3a, 0x76, 0x21, 0x2b, 0x52, 0x8e, 0xfa, 0x85, 0x85, 0x14, 0x4b, 0x2d, 0x7a,
0x1d, 0xa6, 0x9b, 0x84, 0x52, 0xa3, 0x46, 0x0a, 0x39, 0x61, 0xb8, 0x28, 0x0d, 0xa7, 0xb7, 0x02,
0x31, 0x0e, 0xf5, 0xea, 0x2f, 0x0a, 0x2c, 0xc4, 0x7d, 0xda, 0xb4, 0x28, 0x43, 0x77, 0xfb, 0xb8,
0xa7, 0x8d, 0x57, 0x13, 0xf7, 0x16, 0xcc, 0x5b, 0x92, 0xe1, 0x66, 0x42, 0x49, 0x17, 0xef, 0x6e,
0x40, 0xce, 0x62, 0xa4, 0xc9, 0xbb, 0x3e, 0xd9, 0xd3, 0xae, 0x14, 0x92, 0xe8, 0xf3, 0x12, 0x36,
0x77, 0x8d, 0x03, 0xe0, 0x00, 0x47, 0xfd, 0x6b, 0xb2, 0xbb, 0x02, 0xce, 0x47, 0xf4, 0x93, 0x02,
0xab, 0xae, 0x67, 0x39, 0x9e, 0xc5, 0x0e, 0x37, 0x49, 0x8b, 0x34, 0x36, 0x1c, 0x7b, 0xcf, 0xaa,
0xf9, 0x9e, 0xc1, 0x5b, 0x29, 0x8b, 0xda, 0x48, 0x8b, 0xbc, 0x33, 0x14, 0x01, 0x93, 0x3d, 0xe2,
0x11, 0xdb, 0x24, 0xba, 0x2a, 0x53, 0x5a, 0x1d, 0x61, 0x3c, 0x22, 0x15, 0xf4, 0x29, 0xa0, 0xa6,
0xc1, 0x78, 0x47, 0x6b, 0x3b, 0x1e, 0x31, 0x49, 0x95, 0xa3, 0x0a, 0x42, 0xe6, 0x62, 0x76, 0x6c,
0xf5, 0x59, 0xe0, 0x01, 0x5e, 0xe8, 0x5b, 0x05, 0x96, 0xab, 0xfd, 0x43, 0x46, 0xf2, 0xf2, 0xd2,
0x38, 0x8d, 0x1e, 0x30, 0xa3, 0xf4, 0x95, 0x4e, 0xbb, 0xb4, 0x3c, 0x40, 0x81, 0x07, 0x05, 0x43,
0x77, 0x21, 0xe7, 0xf9, 0x0d, 0x42, 0x0b, 0x59, 0x71, 0xbc, 0xa9, 0x51, 0x77, 0x9c, 0x86, 0x65,
0x1e, 0x62, 0xee, 0xf2, 0xb9, 0xc5, 0xea, 0xbb, 0xbe, 0x98, 0x55, 0x34, 0x3e, 0x6b, 0xa1, 0xc2,
0x01, 0xa8, 0xfa, 0x10, 0x96, 0x7a, 0x87, 0x06, 0xaa, 0x01, 0x98, 0xe1, 0x3d, 0xa5, 0x05, 0x45,
0x84, 0x7d, 0x73, 0x7c, 0x56, 0x45, 0x77, 0x3c, 0x9e, 0x97, 0x91, 0x88, 0xe2, 0x2e, 0x68, 0xf5,
0x2c, 0xcc, 0x5d, 0xf5, 0x1c, 0xdf, 0x95, 0x39, 0xa2, 0x35, 0xc8, 0xda, 0x46, 0x33, 0x9c, 0x3e,
0xd1, 0x44, 0xdc, 0x36, 0x9a, 0x04, 0x0b, 0x8d, 0xfa, 0xa3, 0x02, 0xf3, 0x9b, 0x56, 0xd3, 0x62,
0x98, 0x50, 0xd7, 0xb1, 0x29, 0x41, 0x17, 0x13, 0x13, 0xeb, 0x44, 0xcf, 0xc4, 0x3a, 0x92, 0x30,
0xee, 0x9a, 0x55, 0x5f, 0xc2, 0xf4, 0x03, 0x9f, 0xf8, 0x96, 0x5d, 0x93, 0xf3, 0xfa, 0x42, 0x5a,
0x81, 0x37, 0x03, 0xf3, 0x04, 0xdb, 0xf4, 0x59, 0x3e, 0x02, 0xa4, 0x06, 0x87, 0x88, 0xea, 0xdf,
0x0a, 0x9c, 0x10, 0x81, 0x49, 0x75, 0x38, 0x8b, 0xd1, 0x5d, 0x28, 0x18, 0x94, 0xfa, 0x1e, 0xa9,
0x6e, 0x38, 0xb6, 0xe9, 0x7b, 0x9c, 0xff, 0x87, 0xbb, 0x75, 0xc3, 0x23, 0x54, 0x54, 0x93, 0xd3,
0xd7, 0x64, 0x35, 0x85, 0xf5, 0x21, 0x76, 0x78, 0x28, 0x02, 0xba, 0x0f, 0xf3, 0x8d, 0xee, 0xda,
0x65, 0x99, 0x67, 0xd2, 0xca, 0x4c, 0x34, 0x4c, 0x3f, 0x26, 0x33, 0x48, 0x36, 0x1d, 0x27, 0xa1,
0xd5, 0x03, 0x38, 0xb6, 0xcd, 0xef, 0x30, 0x75, 0x7c, 0xcf, 0x24, 0x31, 0x01, 0x51, 0x09, 0x72,
0x2d, 0xe2, 0x55, 0x02, 0x12, 0xe5, 0xf5, 0x3c, 0xa7, 0xdf, 0x67, 0x5c, 0x80, 0x03, 0x39, 0x7a,
0x0f, 0x16, 0xed, 0xd8, 0xf3, 0x36, 0xde, 0xa4, 0x85, 0x29, 0x61, 0xba, 0xdc, 0x69, 0x97, 0x16,
0xb7, 0x93, 0x2a, 0xdc, 0x6b, 0xab, 0xb6, 0x33, 0xb0, 0x32, 0x84, 0xef, 0xe8, 0x36, 0xcc, 0x50,
0xf9, 0x5b, 0x72, 0xf8, 0x64, 0x5a, 0xed, 0xd2, 0x37, 0x9e, 0xb6, 0x21, 0x18, 0x8e, 0xa0, 0x90,
0x03, 0xf3, 0x9e, 0x4c, 0x41, 0xc4, 0x94, 0x53, 0xf7, 0x7c, 0x1a, 0x76, 0x7f, 0x77, 0xe2, 0xe6,
0xe2, 0x6e, 0x40, 0x9c, 0xc4, 0x47, 0x0f, 0x61, 0xa9, 0xab, 0xec, 0x20, 0xe6, 0xa4, 0x88, 0x79,
0x31, 0x2d, 0xe6, 0xc0, 0x43, 0xd1, 0x0b, 0x32, 0xec, 0xd2, 0x76, 0x0f, 0x2c, 0xee, 0x0b, 0xa4,
0xfe, 0x96, 0x81, 0x11, 0x83, 0xf8, 0x25, 0x2c, 0x55, 0xf7, 0x12, 0x4b, 0xd5, 0xfb, 0xcf, 0xff,
0xc2, 0x0c, 0x5d, 0xb2, 0xea, 0x3d, 0x4b, 0xd6, 0x87, 0x2f, 0x10, 0x63, 0xf4, 0xd2, 0xf5, 0x4f,
0x06, 0x5e, 0x19, 0xee, 0x1c, 0x2f, 0x61, 0xd7, 0x13, 0x23, 0xed, 0x52, 0xcf, 0x48, 0x3b, 0x39,
0x06, 0xc4, 0xff, 0x4b, 0x59, 0xcf, 0x52, 0xf6, 0xbb, 0x02, 0xc5, 0xe1, 0x7d, 0x7b, 0x09, 0x4b,
0xda, 0x57, 0xc9, 0x25, 0xed, 0x9d, 0xe7, 0x27, 0xd9, 0x90, 0xa5, 0xed, 0xea, 0x28, 0x6e, 0x45,
0xeb, 0xd5, 0x18, 0x4f, 0xec, 0xaf, 0x23, 0x5b, 0x25, 0xb6, 0xc1, 0x94, 0xbf, 0x12, 0x12, 0xde,
0x1f, 0xd9, 0x46, 0xa5, 0x41, 0x9a, 0xc4, 0x66, 0x92, 0x90, 0x75, 0x98, 0x6e, 0x04, 0x6f, 0xa3,
0xbc, 0xd4, 0xeb, 0x63, 0x3d, 0x49, 0xa3, 0x9e, 0xd2, 0xe0, 0x19, 0x96, 0x66, 0x38, 0x84, 0x57,
0x7f, 0x50, 0x60, 0x2d, 0xed, 0xb2, 0xa2, 0x83, 0x01, 0xcb, 0xce, 0x0b, 0x2c, 0xb2, 0xe3, 0x2f,
0x3f, 0x3f, 0x2b, 0x70, 0x74, 0xd0, 0x4e, 0xc1, 0xe9, 0xcf, 0x17, 0x89, 0x68, 0x0b, 0x88, 0xe8,
0x7f, 0x53, 0x48, 0xb1, 0xd4, 0xa2, 0xd3, 0x30, 0x53, 0x37, 0xec, 0xea, 0xae, 0xf5, 0x75, 0xb8,
0xdf, 0x46, 0x04, 0xfc, 0x44, 0xca, 0x71, 0x64, 0x81, 0xae, 0xc0, 0x92, 0xf0, 0xdb, 0x24, 0x76,
0x8d, 0xd5, 0x45, 0xaf, 0xc4, 0x55, 0xce, 0xc5, 0xef, 0xc1, 0xcd, 0x1e, 0x3d, 0xee, 0xf3, 0x50,
0xff, 0x55, 0x00, 0x3d, 0xcf, 0x3b, 0x7f, 0x0a, 0xf2, 0x86, 0x6b, 0x89, 0x65, 0x2f, 0xb8, 0x02,
0x79, 0x7d, 0xbe, 0xd3, 0x2e, 0xe5, 0xd7, 0x77, 0xae, 0x05, 0x42, 0x1c, 0xeb, 0xb9, 0x71, 0xf8,
0x04, 0x06, 0x4f, 0x9d, 0x34, 0x0e, 0x03, 0x53, 0x1c, 0xeb, 0xd1, 0x65, 0x98, 0x33, 0x1b, 0x3e,
0x65, 0xc4, 0xdb, 0x35, 0x1d, 0x97, 0x88, 0x91, 0x31, 0xa3, 0x1f, 0x95, 0x35, 0xcd, 0x6d, 0x74,
0xe9, 0x70, 0xc2, 0x12, 0x69, 0x00, 0x9c, 0xf0, 0xd4, 0x35, 0x78, 0x9c, 0x9c, 0x88, 0xb3, 0xc0,
0x0f, 0x6c, 0x3b, 0x92, 0xe2, 0x2e, 0x0b, 0xf5, 0x3e, 0x1c, 0xdb, 0x25, 0x5e, 0xcb, 0x32, 0xc9,
0xba, 0x69, 0x3a, 0xbe, 0xcd, 0xc2, 0xb5, 0xb5, 0x0c, 0xf9, 0xc8, 0x4c, 0xde, 0x89, 0x23, 0x32,
0x7e, 0x3e, 0xc2, 0xc2, 0xb1, 0x4d, 0x74, 0x09, 0x33, 0xc3, 0x2f, 0x61, 0x06, 0xa6, 0x63, 0xf8,
0xec, 0xbe, 0x65, 0x57, 0x25, 0xf2, 0xf1, 0xd0, 0xfa, 0xba, 0x65, 0x57, 0x9f, 0xb5, 0x4b, 0xb3,
0xd2, 0x8c, 0x7f, 0x62, 0x61, 0x88, 0xae, 0x41, 0xd6, 0xa7, 0xc4, 0x93, 0xd7, 0xeb, 0x54, 0x1a,
0x99, 0x6f, 0x53, 0xe2, 0x85, 0x9b, 0xcf, 0x0c, 0x47, 0xe6, 0x02, 0x2c, 0x20, 0xd0, 0x16, 0xe4,
0x6a, 0xfc, 0x50, 0xe4, 0xd4, 0x3f, 0x9d, 0x86, 0xd5, 0xbd, 0xce, 0x07, 0x34, 0x10, 0x12, 0x1c,
0xa0, 0xa0, 0x07, 0xb0, 0x40, 0x13, 0x2d, 0x14, 0xc7, 0x35, 0xc6, 0x26, 0x33, 0xb0, 0xf1, 0x3a,
0xea, 0xb4, 0x4b, 0x0b, 0x49, 0x15, 0xee, 0x09, 0xa0, 0x96, 0x61, 0xb6, 0xab, 0xc0, 0xf4, 0xf9,
0xa7, 0x5f, 0x79, 0xf4, 0xb4, 0x38, 0xf1, 0xf8, 0x69, 0x71, 0xe2, 0xc9, 0xd3, 0xe2, 0xc4, 0x37,
0x9d, 0xa2, 0xf2, 0xa8, 0x53, 0x54, 0x1e, 0x77, 0x8a, 0xca, 0x93, 0x4e, 0x51, 0xf9, 0xa3, 0x53,
0x54, 0xbe, 0xfb, 0xb3, 0x38, 0x71, 0xa7, 0x38, 0xfa, 0xff, 0x7a, 0xff, 0x05, 0x00, 0x00, 0xff,
0xff, 0x1e, 0x66, 0x4a, 0x66, 0x11, 0x14, 0x00, 0x00,
// 1554 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4f, 0x6f, 0xdb, 0xc6,
0x12, 0x37, 0x65, 0xc9, 0xb6, 0xc6, 0x7f, 0xb3, 0x8e, 0x61, 0x3d, 0x07, 0x90, 0x1c, 0x3e, 0xe0,
0xe5, 0xbd, 0x97, 0x84, 0x4a, 0xd2, 0xa4, 0x49, 0x5b, 0xf4, 0x8f, 0xe9, 0xb4, 0x69, 0x1a, 0xdb,
0x71, 0xd6, 0x49, 0x5b, 0xa4, 0x01, 0x1a, 0x8a, 0x5a, 0x4b, 0x8c, 0x25, 0x92, 0xd9, 0x25, 0x65,
0xb8, 0xb9, 0x14, 0xfd, 0x04, 0x3d, 0xb7, 0xc7, 0x1e, 0x7a, 0xef, 0x17, 0xe8, 0xb1, 0x41, 0x4f,
0x39, 0xe6, 0xa4, 0x36, 0xea, 0xa9, 0xdf, 0xa0, 0x0d, 0x50, 0xa0, 0xd8, 0xe5, 0x92, 0x14, 0xf5,
0x8f, 0x42, 0x02, 0xe4, 0xd4, 0x9b, 0x39, 0xf3, 0x9b, 0xdf, 0xec, 0xcc, 0xce, 0xcc, 0x8e, 0x0c,
0xd7, 0x0e, 0xae, 0x30, 0xcd, 0x72, 0xca, 0x07, 0x7e, 0x85, 0x50, 0x9b, 0x78, 0x84, 0x95, 0x5b,
0xc4, 0xae, 0x3a, 0xb4, 0x2c, 0x15, 0x86, 0x6b, 0x95, 0xf7, 0x1b, 0xce, 0xa1, 0xe9, 0xd8, 0x1e,
0x75, 0x1a, 0xe5, 0xd6, 0xf9, 0x0a, 0xf1, 0x8c, 0x0b, 0xe5, 0x1a, 0xb1, 0x09, 0x35, 0x3c, 0x52,
0xd5, 0x5c, 0xea, 0x78, 0x0e, 0x2a, 0x06, 0x78, 0xcd, 0x70, 0x2d, 0xad, 0x0b, 0xaf, 0x49, 0xfc,
0xda, 0xd9, 0x9a, 0xe5, 0xd5, 0xfd, 0x8a, 0x66, 0x3a, 0xcd, 0x72, 0xcd, 0xa9, 0x39, 0x65, 0x61,
0x56, 0xf1, 0xf7, 0xc5, 0x97, 0xf8, 0x10, 0x7f, 0x05, 0x74, 0x6b, 0x17, 0x63, 0xf7, 0x4d, 0xc3,
0xac, 0x5b, 0x36, 0xa1, 0x47, 0x65, 0xf7, 0xa0, 0xc6, 0x05, 0xac, 0xdc, 0x24, 0x9e, 0x51, 0x6e,
0x9d, 0xef, 0x3d, 0xc4, 0x5a, 0x79, 0x98, 0x15, 0xf5, 0x6d, 0xcf, 0x6a, 0x92, 0x3e, 0x83, 0xd7,
0xd3, 0x0c, 0x98, 0x59, 0x27, 0x4d, 0xa3, 0xd7, 0x4e, 0xbd, 0x0b, 0xab, 0x1f, 0x34, 0x9c, 0xc3,
0xab, 0x16, 0xf3, 0x2c, 0xbb, 0xe6, 0x5b, 0xac, 0x4e, 0xe8, 0x36, 0xf1, 0xea, 0x4e, 0x15, 0xbd,
0x0b, 0x59, 0xef, 0xc8, 0x25, 0x05, 0x65, 0x5d, 0xf9, 0x6f, 0x5e, 0x3f, 0xfd, 0xb8, 0x5d, 0x9a,
0xe8, 0xb4, 0x4b, 0xd9, 0xdb, 0x47, 0x2e, 0x79, 0xde, 0x2e, 0x9d, 0x18, 0x62, 0xc6, 0xd5, 0x58,
0x18, 0xaa, 0xdf, 0x64, 0x00, 0x38, 0x6a, 0x4f, 0xb8, 0x46, 0xf7, 0x61, 0x86, 0x87, 0x5b, 0x35,
0x3c, 0x43, 0x70, 0xce, 0x5e, 0x38, 0xa7, 0xc5, 0xb9, 0x8e, 0x4e, 0xad, 0xb9, 0x07, 0x35, 0x2e,
0x60, 0x1a, 0x47, 0x6b, 0xad, 0xf3, 0xda, 0xcd, 0xca, 0x03, 0x62, 0x7a, 0xdb, 0xc4, 0x33, 0x74,
0x24, 0x4f, 0x01, 0xb1, 0x0c, 0x47, 0xac, 0x68, 0x17, 0xb2, 0xcc, 0x25, 0x66, 0x21, 0x23, 0xd8,
0x35, 0x6d, 0xf4, 0x4d, 0x6a, 0xf1, 0xd9, 0xf6, 0x5c, 0x62, 0xea, 0x73, 0x61, 0x84, 0xfc, 0x0b,
0x0b, 0x26, 0xf4, 0x29, 0x4c, 0x31, 0xcf, 0xf0, 0x7c, 0x56, 0x98, 0xec, 0x3b, 0x71, 0x1a, 0xa7,
0xb0, 0xd3, 0x17, 0x24, 0xeb, 0x54, 0xf0, 0x8d, 0x25, 0x9f, 0xfa, 0x34, 0x03, 0xcb, 0x31, 0x78,
0xd3, 0xb1, 0xab, 0x96, 0x67, 0x39, 0x36, 0x7a, 0x2b, 0x91, 0xf5, 0x53, 0x3d, 0x59, 0x5f, 0x1d,
0x60, 0x12, 0x67, 0x1c, 0xbd, 0x11, 0x1d, 0x37, 0x23, 0xcc, 0x4f, 0x26, 0x9d, 0x3f, 0x6f, 0x97,
0x16, 0x23, 0xb3, 0xe4, 0x79, 0x50, 0x0b, 0x50, 0xc3, 0x60, 0xde, 0x6d, 0x6a, 0xd8, 0x2c, 0xa0,
0xb5, 0x9a, 0x44, 0x46, 0xfd, 0xff, 0xf1, 0xee, 0x89, 0x5b, 0xe8, 0x6b, 0xd2, 0x25, 0xda, 0xea,
0x63, 0xc3, 0x03, 0x3c, 0xa0, 0xff, 0xc0, 0x14, 0x25, 0x06, 0x73, 0xec, 0x42, 0x56, 0x1c, 0x39,
0xca, 0x17, 0x16, 0x52, 0x2c, 0xb5, 0xe8, 0x7f, 0x30, 0xdd, 0x24, 0x8c, 0x19, 0x35, 0x52, 0xc8,
0x09, 0xe0, 0xa2, 0x04, 0x4e, 0x6f, 0x07, 0x62, 0x1c, 0xea, 0xd5, 0x1f, 0x15, 0x58, 0x88, 0xf3,
0xb4, 0x65, 0x31, 0x0f, 0xdd, 0xeb, 0xab, 0x3d, 0x6d, 0xbc, 0x98, 0xb8, 0xb5, 0xa8, 0xbc, 0x25,
0xe9, 0x6e, 0x26, 0x94, 0x74, 0xd5, 0xdd, 0x4d, 0xc8, 0x59, 0x1e, 0x69, 0xf2, 0xac, 0x4f, 0xf6,
0xa4, 0x2b, 0xa5, 0x48, 0xf4, 0x79, 0x49, 0x9b, 0xbb, 0xce, 0x09, 0x70, 0xc0, 0xa3, 0xfe, 0x3e,
0xd9, 0x1d, 0x01, 0xaf, 0x47, 0xf4, 0xbd, 0x02, 0x6b, 0x2e, 0xb5, 0x1c, 0x6a, 0x79, 0x47, 0x5b,
0xa4, 0x45, 0x1a, 0x9b, 0x8e, 0xbd, 0x6f, 0xd5, 0x7c, 0x6a, 0xf0, 0x54, 0xca, 0xa0, 0x36, 0xd3,
0x3c, 0xef, 0x0e, 0x65, 0xc0, 0x64, 0x9f, 0x50, 0x62, 0x9b, 0x44, 0x57, 0xe5, 0x91, 0xd6, 0x46,
0x80, 0x47, 0x1c, 0x05, 0x7d, 0x04, 0xa8, 0x69, 0x78, 0x3c, 0xa3, 0xb5, 0x5d, 0x4a, 0x4c, 0x52,
0xe5, 0xac, 0xa2, 0x20, 0x73, 0x71, 0x75, 0x6c, 0xf7, 0x21, 0xf0, 0x00, 0x2b, 0xf4, 0x95, 0x02,
0xcb, 0xd5, 0xfe, 0x21, 0x23, 0xeb, 0xf2, 0xf2, 0x38, 0x89, 0x1e, 0x30, 0xa3, 0xf4, 0xd5, 0x4e,
0xbb, 0xb4, 0x3c, 0x40, 0x81, 0x07, 0x39, 0x43, 0xf7, 0x20, 0x47, 0xfd, 0x06, 0x61, 0x85, 0xac,
0xb8, 0xde, 0x54, 0xaf, 0xbb, 0x4e, 0xc3, 0x32, 0x8f, 0x30, 0x37, 0xf9, 0xc4, 0xf2, 0xea, 0x7b,
0xbe, 0x98, 0x55, 0x2c, 0xbe, 0x6b, 0xa1, 0xc2, 0x01, 0xa9, 0xfa, 0x08, 0x96, 0x7a, 0x87, 0x06,
0xaa, 0x01, 0x98, 0x61, 0x9f, 0xb2, 0x82, 0x22, 0xdc, 0xbe, 0x36, 0x7e, 0x55, 0x45, 0x3d, 0x1e,
0xcf, 0xcb, 0x48, 0xc4, 0x70, 0x17, 0xb5, 0x7a, 0x0e, 0xe6, 0xae, 0x51, 0xc7, 0x77, 0xe5, 0x19,
0xd1, 0x3a, 0x64, 0x6d, 0xa3, 0x19, 0x4e, 0x9f, 0x68, 0x22, 0xee, 0x18, 0x4d, 0x82, 0x85, 0x46,
0xfd, 0x4e, 0x81, 0xf9, 0x2d, 0xab, 0x69, 0x79, 0x98, 0x30, 0xd7, 0xb1, 0x19, 0x41, 0x97, 0x12,
0x13, 0xeb, 0x64, 0xcf, 0xc4, 0x3a, 0x96, 0x00, 0x77, 0xcd, 0xaa, 0xcf, 0x60, 0xfa, 0xa1, 0x4f,
0x7c, 0xcb, 0xae, 0xc9, 0x79, 0x7d, 0x31, 0x2d, 0xc0, 0x5b, 0x01, 0x3c, 0x51, 0x6d, 0xfa, 0x2c,
0x1f, 0x01, 0x52, 0x83, 0x43, 0x46, 0xf5, 0xaf, 0x0c, 0x9c, 0x14, 0x8e, 0x49, 0x75, 0x78, 0x15,
0xa3, 0x7b, 0x50, 0x30, 0x18, 0xf3, 0x29, 0xa9, 0x6e, 0x3a, 0xb6, 0xe9, 0x53, 0x5e, 0xff, 0x47,
0x7b, 0x75, 0x83, 0x12, 0x26, 0xa2, 0xc9, 0xe9, 0xeb, 0x32, 0x9a, 0xc2, 0xc6, 0x10, 0x1c, 0x1e,
0xca, 0x80, 0x1e, 0xc0, 0x7c, 0xa3, 0x3b, 0x76, 0x19, 0xe6, 0xd9, 0xb4, 0x30, 0x13, 0x09, 0xd3,
0x57, 0xe4, 0x09, 0x92, 0x49, 0xc7, 0x49, 0x6a, 0xf4, 0x36, 0x2c, 0x36, 0x88, 0x5d, 0x35, 0x2a,
0x0d, 0xb2, 0x4b, 0xa8, 0x49, 0x6c, 0x4f, 0xb4, 0x48, 0x4e, 0x5f, 0xee, 0xb4, 0x4b, 0x8b, 0x5b,
0x49, 0x15, 0xee, 0xc5, 0xa2, 0x9b, 0xb0, 0x52, 0x71, 0x28, 0x75, 0x0e, 0x2d, 0xbb, 0x26, 0xfc,
0x84, 0x24, 0x59, 0x41, 0xf2, 0xaf, 0x4e, 0xbb, 0xb4, 0xa2, 0x0f, 0x02, 0xe0, 0xc1, 0x76, 0xea,
0x21, 0xac, 0xec, 0xf0, 0x99, 0xc2, 0x1c, 0x9f, 0x9a, 0x24, 0x6e, 0x08, 0x54, 0x82, 0x5c, 0x8b,
0xd0, 0x4a, 0x50, 0xd4, 0x79, 0x3d, 0xcf, 0xdb, 0xe1, 0x63, 0x2e, 0xc0, 0x81, 0x9c, 0x47, 0x62,
0xc7, 0x96, 0x77, 0xf0, 0x16, 0x2b, 0x4c, 0x09, 0xa8, 0x88, 0x64, 0x27, 0xa9, 0xc2, 0xbd, 0x58,
0xb5, 0x9d, 0x81, 0xd5, 0x21, 0xfd, 0x87, 0xee, 0xc0, 0x0c, 0x93, 0x7f, 0xcb, 0x9e, 0x3a, 0x95,
0x76, 0x17, 0xd2, 0x36, 0x9e, 0xfe, 0x21, 0x19, 0x8e, 0xa8, 0x90, 0x03, 0xf3, 0x54, 0x1e, 0x41,
0xf8, 0x94, 0xaf, 0xc0, 0x85, 0x34, 0xee, 0xfe, 0xec, 0xc4, 0x97, 0x8d, 0xbb, 0x09, 0x71, 0x92,
0x1f, 0x3d, 0x82, 0xa5, 0xae, 0xb0, 0x03, 0x9f, 0x93, 0xc2, 0xe7, 0xa5, 0x34, 0x9f, 0x03, 0x2f,
0x45, 0x2f, 0x48, 0xb7, 0x4b, 0x3b, 0x3d, 0xb4, 0xb8, 0xcf, 0x91, 0xfa, 0x73, 0x06, 0x46, 0x3c,
0x0c, 0xaf, 0x60, 0xc9, 0xbb, 0x9f, 0x58, 0xf2, 0xde, 0x79, 0xf1, 0x17, 0x6f, 0xe8, 0xd2, 0x57,
0xef, 0x59, 0xfa, 0xde, 0x7b, 0x09, 0x1f, 0xa3, 0x97, 0xc0, 0x3f, 0x32, 0xf0, 0xef, 0xe1, 0xc6,
0xf1, 0x52, 0x78, 0x23, 0x31, 0x62, 0x2f, 0xf7, 0x8c, 0xd8, 0x53, 0x63, 0x50, 0xfc, 0xb3, 0x24,
0xf6, 0x2c, 0x89, 0xbf, 0x28, 0x50, 0x1c, 0x9e, 0xb7, 0x57, 0xb0, 0x34, 0x7e, 0x9e, 0x5c, 0x1a,
0xdf, 0x7c, 0xf1, 0x22, 0x1b, 0xb2, 0x44, 0x5e, 0x1b, 0x55, 0x5b, 0xd1, 0xba, 0x37, 0xc6, 0x93,
0xff, 0xd3, 0xc8, 0x54, 0x89, 0xed, 0x34, 0xe5, 0x57, 0x4b, 0xc2, 0xfa, 0x7d, 0x9b, 0x3f, 0x3d,
0x4d, 0xfe, 0x7a, 0x04, 0x05, 0x59, 0x87, 0xe9, 0x46, 0xf0, 0x56, 0xcb, 0xa6, 0xde, 0x18, 0xeb,
0x89, 0x1c, 0xf5, 0xb4, 0x07, 0x6b, 0x81, 0x84, 0xe1, 0x90, 0x5e, 0xfd, 0x56, 0x81, 0xf5, 0xb4,
0x66, 0x45, 0x87, 0x03, 0x96, 0xaf, 0x97, 0x58, 0xac, 0xc7, 0x5f, 0xc6, 0x7e, 0x50, 0xe0, 0xf8,
0xa0, 0x1d, 0x87, 0x97, 0x3f, 0x5f, 0x6c, 0xa2, 0xad, 0x24, 0x2a, 0xff, 0x5b, 0x42, 0x8a, 0xa5,
0x16, 0x9d, 0x81, 0x99, 0xba, 0x61, 0x57, 0xf7, 0xac, 0x2f, 0xc2, 0x7d, 0x3b, 0x2a, 0xc0, 0x0f,
0xa5, 0x1c, 0x47, 0x08, 0x74, 0x15, 0x96, 0x84, 0xdd, 0x16, 0xb1, 0x6b, 0x5e, 0x5d, 0xe4, 0x4a,
0x2e, 0x0d, 0xd1, 0x7b, 0x70, 0xab, 0x47, 0x8f, 0xfb, 0x2c, 0xd4, 0x3f, 0x15, 0x40, 0x2f, 0xf2,
0xce, 0x9f, 0x86, 0xbc, 0xe1, 0x5a, 0x62, 0xf9, 0x0c, 0x5a, 0x20, 0xaf, 0xcf, 0x77, 0xda, 0xa5,
0xfc, 0xc6, 0xee, 0xf5, 0x40, 0x88, 0x63, 0x3d, 0x07, 0x87, 0x4f, 0x60, 0xf0, 0xd4, 0x49, 0x70,
0xe8, 0x98, 0xe1, 0x58, 0x8f, 0xae, 0xc0, 0x9c, 0xd9, 0xf0, 0x99, 0x47, 0xe8, 0x9e, 0xe9, 0xb8,
0x44, 0x8c, 0x8c, 0x19, 0xfd, 0xb8, 0x8c, 0x69, 0x6e, 0xb3, 0x4b, 0x87, 0x13, 0x48, 0xa4, 0x01,
0xf0, 0x82, 0x67, 0xae, 0xc1, 0xfd, 0xe4, 0x84, 0x9f, 0x05, 0x7e, 0x61, 0x3b, 0x91, 0x14, 0x77,
0x21, 0xd4, 0x07, 0xb0, 0xb2, 0x47, 0x68, 0xcb, 0x32, 0xc9, 0x86, 0x69, 0x3a, 0xbe, 0xed, 0x85,
0x6b, 0x74, 0x19, 0xf2, 0x11, 0x4c, 0xf6, 0xc4, 0x31, 0xe9, 0x3f, 0x1f, 0x71, 0xe1, 0x18, 0x13,
0x35, 0x61, 0x66, 0x78, 0x13, 0x66, 0x60, 0x3a, 0xa6, 0xcf, 0x1e, 0x58, 0x76, 0x55, 0x32, 0x9f,
0x08, 0xd1, 0x37, 0x2c, 0xbb, 0xfa, 0xbc, 0x5d, 0x9a, 0x95, 0x30, 0xfe, 0x89, 0x05, 0x10, 0x5d,
0x87, 0xac, 0xcf, 0x08, 0x95, 0xed, 0x75, 0x3a, 0xad, 0x98, 0xef, 0x30, 0x42, 0xc3, 0xcd, 0x67,
0x86, 0x33, 0x73, 0x01, 0x16, 0x14, 0x68, 0x1b, 0x72, 0x35, 0x7e, 0x29, 0x72, 0xea, 0x9f, 0x49,
0xe3, 0xea, 0xfe, 0x79, 0x11, 0x94, 0x81, 0x90, 0xe0, 0x80, 0x05, 0x3d, 0x84, 0x05, 0x96, 0x48,
0xa1, 0xb8, 0xae, 0x31, 0x36, 0x99, 0x81, 0x89, 0xd7, 0x51, 0xa7, 0x5d, 0x5a, 0x48, 0xaa, 0x70,
0x8f, 0x03, 0xb5, 0x0c, 0xb3, 0x5d, 0x01, 0xa6, 0xcf, 0x3f, 0xfd, 0xea, 0xe3, 0x67, 0xc5, 0x89,
0x27, 0xcf, 0x8a, 0x13, 0x4f, 0x9f, 0x15, 0x27, 0xbe, 0xec, 0x14, 0x95, 0xc7, 0x9d, 0xa2, 0xf2,
0xa4, 0x53, 0x54, 0x9e, 0x76, 0x8a, 0xca, 0xaf, 0x9d, 0xa2, 0xf2, 0xf5, 0x6f, 0xc5, 0x89, 0xbb,
0xc5, 0xd1, 0xff, 0x67, 0xfc, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x87, 0x72, 0xbf, 0xe2, 0xa1, 0x14,
0x00, 0x00,
}
func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) {
@@ -1154,6 +1158,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i
_ = i
var l int
_ = l
if m.BorrowingLimitPercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent))
i--
dAtA[i] = 0x20
}
if m.LendablePercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent))
i--
dAtA[i] = 0x18
}
{
size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -1903,6 +1917,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) {
n += 1 + sovGenerated(uint64(m.AssuredConcurrencyShares))
l = m.LimitResponse.Size()
n += 1 + l + sovGenerated(uint64(l))
if m.LendablePercent != nil {
n += 1 + sovGenerated(uint64(*m.LendablePercent))
}
if m.BorrowingLimitPercent != nil {
n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent))
}
return n
}
@@ -2258,6 +2278,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string {
s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`,
`AssuredConcurrencyShares:` + fmt.Sprintf("%v", this.AssuredConcurrencyShares) + `,`,
`LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`,
`LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`,
`BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`,
`}`,
}, "")
return s
@@ -3542,6 +3564,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.LendablePercent = &v
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.BorrowingLimitPercent = &v
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])

View File

@@ -176,6 +176,35 @@ message LimitedPriorityLevelConfiguration {
// `limitResponse` indicates what to do with requests that can not be executed right now
optional LimitResponse limitResponse = 2;
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
optional int32 lendablePercent = 3;
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
optional int32 borrowingLimitPercent = 4;
}
// NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the

View File

@@ -474,6 +474,35 @@ type LimitedPriorityLevelConfiguration struct {
// `limitResponse` indicates what to do with requests that can not be executed right now
LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"`
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"`
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"`
}
// LimitResponse defines how to handle requests that can not be executed right now.

View File

@@ -114,6 +114,8 @@ var map_LimitedPriorityLevelConfiguration = map[string]string{
"": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?",
"assuredConcurrencyShares": "`assuredConcurrencyShares` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) ",
"limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now",
"lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
}
func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string {

View File

@@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse {
func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) {
*out = *in
in.LimitResponse.DeepCopyInto(&out.LimitResponse)
if in.LendablePercent != nil {
in, out := &in.LendablePercent, &out.LendablePercent
*out = new(int32)
**out = **in
}
if in.BorrowingLimitPercent != nil {
in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent
*out = new(int32)
**out = **in
}
return
}

View File

@@ -689,101 +689,104 @@ func init() {
}
var fileDescriptor_803504887082f044 = []byte{
// 1498 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4b, 0x73, 0x13, 0xc7,
0x16, 0xf6, 0xc8, 0x92, 0x6d, 0x1d, 0x3f, 0x69, 0x43, 0x59, 0x65, 0xaa, 0x24, 0x33, 0xb7, 0xea,
0x72, 0xef, 0x05, 0x46, 0x3c, 0x2f, 0x24, 0xa9, 0x3c, 0x18, 0x93, 0x10, 0x82, 0x6d, 0x4c, 0x1b,
0x92, 0x14, 0xa1, 0x2a, 0x8c, 0x47, 0x6d, 0xa9, 0xb1, 0x34, 0x33, 0x4c, 0xf7, 0xc8, 0xe5, 0xb0,
0x49, 0xe5, 0x17, 0x64, 0x9d, 0x2c, 0xb3, 0xc8, 0x3e, 0x7f, 0x20, 0xcb, 0x50, 0x59, 0xb1, 0x64,
0xa5, 0x04, 0x65, 0x95, 0x45, 0xf6, 0x09, 0xab, 0x54, 0xf7, 0xb4, 0x66, 0x34, 0x7a, 0x8d, 0x0a,
0xaa, 0x58, 0x65, 0xa7, 0x39, 0x8f, 0xef, 0x3c, 0xfa, 0xeb, 0xd3, 0xc7, 0x86, 0xeb, 0xfb, 0x57,
0x98, 0x41, 0xdd, 0xf2, 0x7e, 0xb0, 0x4b, 0x7c, 0x87, 0x70, 0xc2, 0xca, 0x4d, 0xe2, 0x54, 0x5c,
0xbf, 0xac, 0x14, 0x96, 0x47, 0xcb, 0x7b, 0x75, 0xf7, 0xc0, 0x76, 0x1d, 0xee, 0xbb, 0xf5, 0x72,
0xf3, 0xdc, 0x2e, 0xe1, 0xd6, 0x85, 0x72, 0x95, 0x38, 0xc4, 0xb7, 0x38, 0xa9, 0x18, 0x9e, 0xef,
0x72, 0x17, 0x15, 0x43, 0x7b, 0xc3, 0xf2, 0xa8, 0xd1, 0x65, 0x6f, 0x28, 0xfb, 0xd5, 0x33, 0x55,
0xca, 0x6b, 0xc1, 0xae, 0x61, 0xbb, 0x8d, 0x72, 0xd5, 0xad, 0xba, 0x65, 0xe9, 0xb6, 0x1b, 0xec,
0xc9, 0x2f, 0xf9, 0x21, 0x7f, 0x85, 0x70, 0xab, 0x17, 0xe3, 0xf0, 0x0d, 0xcb, 0xae, 0x51, 0x87,
0xf8, 0x87, 0x65, 0x6f, 0xbf, 0x2a, 0x04, 0xac, 0xdc, 0x20, 0xdc, 0x2a, 0x37, 0xcf, 0xf5, 0x26,
0xb1, 0x5a, 0x1e, 0xe6, 0xe5, 0x07, 0x0e, 0xa7, 0x0d, 0xd2, 0xe7, 0xf0, 0xff, 0x34, 0x07, 0x66,
0xd7, 0x48, 0xc3, 0xea, 0xf5, 0xd3, 0xef, 0xc1, 0xca, 0x07, 0x75, 0xf7, 0xe0, 0x1a, 0x65, 0x9c,
0x3a, 0xd5, 0x80, 0xb2, 0x1a, 0xf1, 0x37, 0x09, 0xaf, 0xb9, 0x15, 0xf4, 0x2e, 0x64, 0xf9, 0xa1,
0x47, 0x0a, 0xda, 0x9a, 0xf6, 0x9f, 0xbc, 0x79, 0xea, 0x49, 0xab, 0x34, 0xd1, 0x6e, 0x95, 0xb2,
0x77, 0x0e, 0x3d, 0xf2, 0xa2, 0x55, 0x3a, 0x3e, 0xc4, 0x4d, 0xa8, 0xb1, 0x74, 0xd4, 0xbf, 0xc9,
0x00, 0x08, 0xab, 0x1d, 0x19, 0x1a, 0x3d, 0x80, 0x19, 0x51, 0x6e, 0xc5, 0xe2, 0x96, 0xc4, 0x9c,
0x3d, 0x7f, 0xd6, 0x88, 0x7b, 0x1d, 0x65, 0x6d, 0x78, 0xfb, 0x55, 0x21, 0x60, 0x86, 0xb0, 0x36,
0x9a, 0xe7, 0x8c, 0x5b, 0xbb, 0x0f, 0x89, 0xcd, 0x37, 0x09, 0xb7, 0x4c, 0xa4, 0xb2, 0x80, 0x58,
0x86, 0x23, 0x54, 0xb4, 0x0d, 0x59, 0xe6, 0x11, 0xbb, 0x90, 0x91, 0xe8, 0x86, 0x31, 0xfa, 0x24,
0x8d, 0x38, 0xb7, 0x1d, 0x8f, 0xd8, 0xe6, 0x5c, 0xa7, 0x42, 0xf1, 0x85, 0x25, 0x12, 0xfa, 0x14,
0xa6, 0x18, 0xb7, 0x78, 0xc0, 0x0a, 0x93, 0x7d, 0x19, 0xa7, 0x61, 0x4a, 0x3f, 0x73, 0x41, 0xa1,
0x4e, 0x85, 0xdf, 0x58, 0xe1, 0xe9, 0xcf, 0x32, 0xb0, 0x1c, 0x1b, 0xaf, 0xbb, 0x4e, 0x85, 0x72,
0xea, 0x3a, 0xe8, 0xad, 0x44, 0xd7, 0x4f, 0xf6, 0x74, 0x7d, 0x65, 0x80, 0x4b, 0xdc, 0x71, 0xf4,
0x46, 0x94, 0x6e, 0x46, 0xba, 0x9f, 0x48, 0x06, 0x7f, 0xd1, 0x2a, 0x2d, 0x46, 0x6e, 0xc9, 0x7c,
0x50, 0x13, 0x50, 0xdd, 0x62, 0xfc, 0x8e, 0x6f, 0x39, 0x2c, 0x84, 0xa5, 0x0d, 0xa2, 0xaa, 0xfe,
0xdf, 0x78, 0xe7, 0x24, 0x3c, 0xcc, 0x55, 0x15, 0x12, 0x6d, 0xf4, 0xa1, 0xe1, 0x01, 0x11, 0xd0,
0xbf, 0x61, 0xca, 0x27, 0x16, 0x73, 0x9d, 0x42, 0x56, 0xa6, 0x1c, 0xf5, 0x0b, 0x4b, 0x29, 0x56,
0x5a, 0xf4, 0x5f, 0x98, 0x6e, 0x10, 0xc6, 0xac, 0x2a, 0x29, 0xe4, 0xa4, 0xe1, 0xa2, 0x32, 0x9c,
0xde, 0x0c, 0xc5, 0xb8, 0xa3, 0xd7, 0x7f, 0xd4, 0x60, 0x21, 0xee, 0xd3, 0x06, 0x65, 0x1c, 0xdd,
0xef, 0xe3, 0x9e, 0x31, 0x5e, 0x4d, 0xc2, 0x5b, 0x32, 0x6f, 0x49, 0x85, 0x9b, 0xe9, 0x48, 0xba,
0x78, 0x77, 0x0b, 0x72, 0x94, 0x93, 0x86, 0xe8, 0xfa, 0x64, 0x4f, 0xbb, 0x52, 0x48, 0x62, 0xce,
0x2b, 0xd8, 0xdc, 0x0d, 0x01, 0x80, 0x43, 0x1c, 0xfd, 0xf7, 0xc9, 0xee, 0x0a, 0x04, 0x1f, 0xd1,
0xf7, 0x1a, 0xac, 0x7a, 0x3e, 0x75, 0x7d, 0xca, 0x0f, 0x37, 0x48, 0x93, 0xd4, 0xd7, 0x5d, 0x67,
0x8f, 0x56, 0x03, 0xdf, 0x12, 0xad, 0x54, 0x45, 0xad, 0xa7, 0x45, 0xde, 0x1e, 0x8a, 0x80, 0xc9,
0x1e, 0xf1, 0x89, 0x63, 0x13, 0x53, 0x57, 0x29, 0xad, 0x8e, 0x30, 0x1e, 0x91, 0x0a, 0xfa, 0x08,
0x50, 0xc3, 0xe2, 0xa2, 0xa3, 0xd5, 0x6d, 0x9f, 0xd8, 0xa4, 0x22, 0x50, 0x25, 0x21, 0x73, 0x31,
0x3b, 0x36, 0xfb, 0x2c, 0xf0, 0x00, 0x2f, 0xf4, 0x95, 0x06, 0xcb, 0x95, 0xfe, 0x21, 0xa3, 0x78,
0x79, 0x79, 0x9c, 0x46, 0x0f, 0x98, 0x51, 0xe6, 0x4a, 0xbb, 0x55, 0x5a, 0x1e, 0xa0, 0xc0, 0x83,
0x82, 0xa1, 0xfb, 0x90, 0xf3, 0x83, 0x3a, 0x61, 0x85, 0xac, 0x3c, 0xde, 0xd4, 0xa8, 0xdb, 0x6e,
0x9d, 0xda, 0x87, 0x58, 0xb8, 0x7c, 0x42, 0x79, 0x6d, 0x27, 0x90, 0xb3, 0x8a, 0xc5, 0x67, 0x2d,
0x55, 0x38, 0x04, 0xd5, 0x1f, 0xc3, 0x52, 0xef, 0xd0, 0x40, 0x55, 0x00, 0xbb, 0x73, 0x4f, 0x59,
0x41, 0x93, 0x61, 0x2f, 0x8c, 0xcf, 0xaa, 0xe8, 0x8e, 0xc7, 0xf3, 0x32, 0x12, 0x31, 0xdc, 0x05,
0xad, 0x9f, 0x85, 0xb9, 0xeb, 0xbe, 0x1b, 0x78, 0x2a, 0x47, 0xb4, 0x06, 0x59, 0xc7, 0x6a, 0x74,
0xa6, 0x4f, 0x34, 0x11, 0xb7, 0xac, 0x06, 0xc1, 0x52, 0xa3, 0x7f, 0xa7, 0xc1, 0xfc, 0x06, 0x6d,
0x50, 0x8e, 0x09, 0xf3, 0x5c, 0x87, 0x11, 0x74, 0x29, 0x31, 0xb1, 0x4e, 0xf4, 0x4c, 0xac, 0x23,
0x09, 0xe3, 0xae, 0x59, 0xf5, 0x19, 0x4c, 0x3f, 0x0a, 0x48, 0x40, 0x9d, 0xaa, 0x9a, 0xd7, 0x17,
0xd3, 0x0a, 0xbc, 0x1d, 0x9a, 0x27, 0xd8, 0x66, 0xce, 0x8a, 0x11, 0xa0, 0x34, 0xb8, 0x83, 0xa8,
0xff, 0xa1, 0xc1, 0x09, 0x19, 0x98, 0x54, 0x86, 0xb3, 0x18, 0xdd, 0x87, 0x82, 0xe3, 0x36, 0xa8,
0x63, 0x09, 0xb9, 0x1d, 0xf8, 0x82, 0xff, 0x87, 0x3b, 0x35, 0xcb, 0x27, 0x4c, 0x56, 0x93, 0x33,
0xd7, 0x54, 0x35, 0x85, 0xad, 0x21, 0x76, 0x78, 0x28, 0x02, 0x7a, 0x08, 0xf3, 0xf5, 0xee, 0xda,
0x55, 0x99, 0x67, 0xd2, 0xca, 0x4c, 0x34, 0xcc, 0x3c, 0xa6, 0x32, 0x48, 0x36, 0x1d, 0x27, 0xa1,
0xf5, 0x03, 0x38, 0xb6, 0x25, 0xee, 0x30, 0x73, 0x03, 0xdf, 0x26, 0x31, 0x01, 0x51, 0x09, 0x72,
0x4d, 0xe2, 0xef, 0x86, 0x24, 0xca, 0x9b, 0x79, 0x41, 0xbf, 0x8f, 0x85, 0x00, 0x87, 0x72, 0xf4,
0x36, 0x2c, 0x3a, 0xb1, 0xe7, 0x5d, 0xbc, 0xc1, 0x0a, 0x53, 0xd2, 0x74, 0xb9, 0xdd, 0x2a, 0x2d,
0x6e, 0x25, 0x55, 0xb8, 0xd7, 0x56, 0x6f, 0x65, 0x60, 0x65, 0x08, 0xdf, 0xd1, 0x5d, 0x98, 0x61,
0xea, 0xb7, 0xe2, 0xf0, 0xc9, 0xb4, 0xda, 0x95, 0x6f, 0x3c, 0x6d, 0x3b, 0x60, 0x38, 0x82, 0x42,
0x2e, 0xcc, 0xfb, 0x2a, 0x05, 0x19, 0x53, 0x4d, 0xdd, 0xf3, 0x69, 0xd8, 0xfd, 0xdd, 0x89, 0x9b,
0x8b, 0xbb, 0x01, 0x71, 0x12, 0x1f, 0x3d, 0x86, 0xa5, 0xae, 0xb2, 0xc3, 0x98, 0x93, 0x32, 0xe6,
0xa5, 0xb4, 0x98, 0x03, 0x0f, 0xc5, 0x2c, 0xa8, 0xb0, 0x4b, 0x5b, 0x3d, 0xb0, 0xb8, 0x2f, 0x90,
0xfe, 0x73, 0x06, 0x46, 0x0c, 0xe2, 0xd7, 0xb0, 0x54, 0x3d, 0x48, 0x2c, 0x55, 0xef, 0xbc, 0xfc,
0x0b, 0x33, 0x74, 0xc9, 0xaa, 0xf5, 0x2c, 0x59, 0xef, 0xbd, 0x42, 0x8c, 0xd1, 0x4b, 0xd7, 0x9f,
0x19, 0xf8, 0xd7, 0x70, 0xe7, 0x78, 0x09, 0xbb, 0x99, 0x18, 0x69, 0x97, 0x7b, 0x46, 0xda, 0xc9,
0x31, 0x20, 0xfe, 0x59, 0xca, 0x7a, 0x96, 0xb2, 0x5f, 0x34, 0x28, 0x0e, 0xef, 0xdb, 0x6b, 0x58,
0xd2, 0x3e, 0x4f, 0x2e, 0x69, 0x6f, 0xbe, 0x3c, 0xc9, 0x86, 0x2c, 0x6d, 0xd7, 0x47, 0x71, 0x2b,
0x5a, 0xaf, 0xc6, 0x78, 0x62, 0x7f, 0x1a, 0xd9, 0x2a, 0xb9, 0x0d, 0xa6, 0xfc, 0x95, 0x90, 0xf0,
0x7e, 0xdf, 0xb1, 0x76, 0xeb, 0xa4, 0x41, 0x1c, 0xae, 0x08, 0x59, 0x83, 0xe9, 0x7a, 0xf8, 0x36,
0xaa, 0x4b, 0x7d, 0x75, 0xac, 0x27, 0x69, 0xd4, 0x53, 0x1a, 0x3e, 0xc3, 0xca, 0x0c, 0x77, 0xe0,
0xf5, 0x6f, 0x35, 0x58, 0x4b, 0xbb, 0xac, 0xe8, 0x60, 0xc0, 0xb2, 0xf3, 0x0a, 0x8b, 0xec, 0xf8,
0xcb, 0xcf, 0x0f, 0x1a, 0x1c, 0x1d, 0xb4, 0x53, 0x08, 0xfa, 0x8b, 0x45, 0x22, 0xda, 0x02, 0x22,
0xfa, 0xdf, 0x96, 0x52, 0xac, 0xb4, 0xe8, 0x34, 0xcc, 0xd4, 0x2c, 0xa7, 0xb2, 0x43, 0xbf, 0xe8,
0xec, 0xb7, 0x11, 0x01, 0x3f, 0x54, 0x72, 0x1c, 0x59, 0xa0, 0x6b, 0xb0, 0x24, 0xfd, 0x36, 0x88,
0x53, 0xe5, 0x35, 0xd9, 0x2b, 0x79, 0x95, 0x73, 0xf1, 0x7b, 0x70, 0xbb, 0x47, 0x8f, 0xfb, 0x3c,
0xf4, 0xbf, 0x34, 0x40, 0x2f, 0xf3, 0xce, 0x9f, 0x82, 0xbc, 0xe5, 0x51, 0xb9, 0xec, 0x85, 0x57,
0x20, 0x6f, 0xce, 0xb7, 0x5b, 0xa5, 0xfc, 0xd5, 0xed, 0x1b, 0xa1, 0x10, 0xc7, 0x7a, 0x61, 0xdc,
0x79, 0x02, 0xc3, 0xa7, 0x4e, 0x19, 0x77, 0x02, 0x33, 0x1c, 0xeb, 0xd1, 0x15, 0x98, 0xb3, 0xeb,
0x01, 0xe3, 0xc4, 0xdf, 0xb1, 0x5d, 0x8f, 0xc8, 0x91, 0x31, 0x63, 0x1e, 0x55, 0x35, 0xcd, 0xad,
0x77, 0xe9, 0x70, 0xc2, 0x12, 0x19, 0x00, 0x82, 0xf0, 0xcc, 0xb3, 0x44, 0x9c, 0x9c, 0x8c, 0xb3,
0x20, 0x0e, 0x6c, 0x2b, 0x92, 0xe2, 0x2e, 0x0b, 0xfd, 0x21, 0x1c, 0xdb, 0x21, 0x7e, 0x93, 0xda,
0xe4, 0xaa, 0x6d, 0xbb, 0x81, 0xc3, 0x3b, 0x6b, 0x6b, 0x19, 0xf2, 0x91, 0x99, 0xba, 0x13, 0x47,
0x54, 0xfc, 0x7c, 0x84, 0x85, 0x63, 0x9b, 0xe8, 0x12, 0x66, 0x86, 0x5f, 0xc2, 0x0c, 0x4c, 0xc7,
0xf0, 0xd9, 0x7d, 0xea, 0x54, 0x14, 0xf2, 0xf1, 0x8e, 0xf5, 0x4d, 0xea, 0x54, 0x5e, 0xb4, 0x4a,
0xb3, 0xca, 0x4c, 0x7c, 0x62, 0x69, 0x88, 0x6e, 0x40, 0x36, 0x60, 0xc4, 0x57, 0xd7, 0xeb, 0x54,
0x1a, 0x99, 0xef, 0x32, 0xe2, 0x77, 0x36, 0x9f, 0x19, 0x81, 0x2c, 0x04, 0x58, 0x42, 0xa0, 0x4d,
0xc8, 0x55, 0xc5, 0xa1, 0xa8, 0xa9, 0x7f, 0x3a, 0x0d, 0xab, 0x7b, 0x9d, 0x0f, 0x69, 0x20, 0x25,
0x38, 0x44, 0x41, 0x8f, 0x60, 0x81, 0x25, 0x5a, 0x28, 0x8f, 0x6b, 0x8c, 0x4d, 0x66, 0x60, 0xe3,
0x4d, 0xd4, 0x6e, 0x95, 0x16, 0x92, 0x2a, 0xdc, 0x13, 0x40, 0x2f, 0xc3, 0x6c, 0x57, 0x81, 0xe9,
0xf3, 0xcf, 0xbc, 0xf6, 0xe4, 0x79, 0x71, 0xe2, 0xe9, 0xf3, 0xe2, 0xc4, 0xb3, 0xe7, 0xc5, 0x89,
0x2f, 0xdb, 0x45, 0xed, 0x49, 0xbb, 0xa8, 0x3d, 0x6d, 0x17, 0xb5, 0x67, 0xed, 0xa2, 0xf6, 0x6b,
0xbb, 0xa8, 0x7d, 0xfd, 0x5b, 0x71, 0xe2, 0x5e, 0x71, 0xf4, 0xff, 0xf5, 0xfe, 0x0e, 0x00, 0x00,
0xff, 0xff, 0x3d, 0xec, 0x35, 0xcf, 0x11, 0x14, 0x00, 0x00,
// 1552 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0xdb, 0x46,
0x13, 0x36, 0x65, 0xc9, 0xb6, 0xd6, 0x9f, 0x59, 0xc7, 0xb0, 0x5e, 0x07, 0x90, 0x1c, 0xbe, 0xc0,
0x9b, 0xb7, 0x4d, 0x42, 0xe5, 0xb3, 0x49, 0x5b, 0xf4, 0x23, 0x74, 0xda, 0x34, 0x8d, 0xed, 0x38,
0xeb, 0xa4, 0x2d, 0xd2, 0x00, 0x0d, 0x45, 0xad, 0xa9, 0x8d, 0x25, 0x92, 0xd9, 0x25, 0x65, 0xb8,
0xb9, 0x14, 0xfd, 0x05, 0x3d, 0xb7, 0xc7, 0x1e, 0x7a, 0xef, 0x1f, 0xe8, 0xb1, 0x41, 0x4f, 0x39,
0xe6, 0xa4, 0x36, 0xea, 0xa9, 0xff, 0xa0, 0x0d, 0x50, 0xa0, 0xd8, 0xe5, 0x92, 0x14, 0xa9, 0x0f,
0x0a, 0x09, 0x90, 0x53, 0x6f, 0xe6, 0xcc, 0x33, 0xcf, 0xec, 0xcc, 0xce, 0xcc, 0x8e, 0x0c, 0xae,
0xed, 0x5f, 0x66, 0x1a, 0x71, 0xaa, 0xfb, 0x7e, 0x0d, 0x53, 0x1b, 0x7b, 0x98, 0x55, 0xdb, 0xd8,
0xae, 0x3b, 0xb4, 0x2a, 0x15, 0x86, 0x4b, 0xaa, 0x7b, 0x4d, 0xe7, 0xc0, 0x74, 0x6c, 0x8f, 0x3a,
0xcd, 0x6a, 0xfb, 0x6c, 0x0d, 0x7b, 0xc6, 0xf9, 0xaa, 0x85, 0x6d, 0x4c, 0x0d, 0x0f, 0xd7, 0x35,
0x97, 0x3a, 0x9e, 0x03, 0xcb, 0x01, 0x5e, 0x33, 0x5c, 0xa2, 0xf5, 0xe0, 0x35, 0x89, 0x5f, 0x3b,
0x6d, 0x11, 0xaf, 0xe1, 0xd7, 0x34, 0xd3, 0x69, 0x55, 0x2d, 0xc7, 0x72, 0xaa, 0xc2, 0xac, 0xe6,
0xef, 0x89, 0x2f, 0xf1, 0x21, 0xfe, 0x0a, 0xe8, 0xd6, 0x2e, 0xc4, 0xee, 0x5b, 0x86, 0xd9, 0x20,
0x36, 0xa6, 0x87, 0x55, 0x77, 0xdf, 0xe2, 0x02, 0x56, 0x6d, 0x61, 0xcf, 0xa8, 0xb6, 0xcf, 0xa6,
0x0f, 0xb1, 0x56, 0x1d, 0x66, 0x45, 0x7d, 0xdb, 0x23, 0x2d, 0xdc, 0x67, 0xf0, 0x46, 0x96, 0x01,
0x33, 0x1b, 0xb8, 0x65, 0xa4, 0xed, 0xd4, 0xbb, 0x60, 0xf5, 0xc3, 0xa6, 0x73, 0x70, 0x95, 0x30,
0x8f, 0xd8, 0x96, 0x4f, 0x58, 0x03, 0xd3, 0x2d, 0xec, 0x35, 0x9c, 0x3a, 0x7c, 0x0f, 0xe4, 0xbd,
0x43, 0x17, 0x97, 0x94, 0x75, 0xe5, 0xff, 0x45, 0xfd, 0xe4, 0xe3, 0x4e, 0x65, 0xa2, 0xdb, 0xa9,
0xe4, 0x6f, 0x1f, 0xba, 0xf8, 0x79, 0xa7, 0x72, 0x6c, 0x88, 0x19, 0x57, 0x23, 0x61, 0xa8, 0x7e,
0x9b, 0x03, 0x80, 0xa3, 0x76, 0x85, 0x6b, 0x78, 0x1f, 0xcc, 0xf0, 0x70, 0xeb, 0x86, 0x67, 0x08,
0xce, 0xd9, 0x73, 0x67, 0xb4, 0x38, 0xd7, 0xd1, 0xa9, 0x35, 0x77, 0xdf, 0xe2, 0x02, 0xa6, 0x71,
0xb4, 0xd6, 0x3e, 0xab, 0xdd, 0xac, 0x3d, 0xc0, 0xa6, 0xb7, 0x85, 0x3d, 0x43, 0x87, 0xf2, 0x14,
0x20, 0x96, 0xa1, 0x88, 0x15, 0xee, 0x80, 0x3c, 0x73, 0xb1, 0x59, 0xca, 0x09, 0x76, 0x4d, 0x1b,
0x7d, 0x93, 0x5a, 0x7c, 0xb6, 0x5d, 0x17, 0x9b, 0xfa, 0x5c, 0x18, 0x21, 0xff, 0x42, 0x82, 0x09,
0x7e, 0x06, 0xa6, 0x98, 0x67, 0x78, 0x3e, 0x2b, 0x4d, 0xf6, 0x9d, 0x38, 0x8b, 0x53, 0xd8, 0xe9,
0x0b, 0x92, 0x75, 0x2a, 0xf8, 0x46, 0x92, 0x4f, 0x7d, 0x9a, 0x03, 0xcb, 0x31, 0x78, 0xc3, 0xb1,
0xeb, 0xc4, 0x23, 0x8e, 0x0d, 0xdf, 0x4e, 0x64, 0xfd, 0x44, 0x2a, 0xeb, 0xab, 0x03, 0x4c, 0xe2,
0x8c, 0xc3, 0x37, 0xa3, 0xe3, 0xe6, 0x84, 0xf9, 0xf1, 0xa4, 0xf3, 0xe7, 0x9d, 0xca, 0x62, 0x64,
0x96, 0x3c, 0x0f, 0x6c, 0x03, 0xd8, 0x34, 0x98, 0x77, 0x9b, 0x1a, 0x36, 0x0b, 0x68, 0x49, 0x0b,
0xcb, 0xa8, 0x5f, 0x1f, 0xef, 0x9e, 0xb8, 0x85, 0xbe, 0x26, 0x5d, 0xc2, 0xcd, 0x3e, 0x36, 0x34,
0xc0, 0x03, 0xfc, 0x1f, 0x98, 0xa2, 0xd8, 0x60, 0x8e, 0x5d, 0xca, 0x8b, 0x23, 0x47, 0xf9, 0x42,
0x42, 0x8a, 0xa4, 0x16, 0xbe, 0x06, 0xa6, 0x5b, 0x98, 0x31, 0xc3, 0xc2, 0xa5, 0x82, 0x00, 0x2e,
0x4a, 0xe0, 0xf4, 0x56, 0x20, 0x46, 0xa1, 0x5e, 0xfd, 0x49, 0x01, 0x0b, 0x71, 0x9e, 0x36, 0x09,
0xf3, 0xe0, 0xbd, 0xbe, 0xda, 0xd3, 0xc6, 0x8b, 0x89, 0x5b, 0x8b, 0xca, 0x5b, 0x92, 0xee, 0x66,
0x42, 0x49, 0x4f, 0xdd, 0xdd, 0x04, 0x05, 0xe2, 0xe1, 0x16, 0xcf, 0xfa, 0x64, 0x2a, 0x5d, 0x19,
0x45, 0xa2, 0xcf, 0x4b, 0xda, 0xc2, 0x75, 0x4e, 0x80, 0x02, 0x1e, 0xf5, 0x8f, 0xc9, 0xde, 0x08,
0x78, 0x3d, 0xc2, 0x1f, 0x14, 0xb0, 0xe6, 0x52, 0xe2, 0x50, 0xe2, 0x1d, 0x6e, 0xe2, 0x36, 0x6e,
0x6e, 0x38, 0xf6, 0x1e, 0xb1, 0x7c, 0x6a, 0xf0, 0x54, 0xca, 0xa0, 0x36, 0xb2, 0x3c, 0xef, 0x0c,
0x65, 0x40, 0x78, 0x0f, 0x53, 0x6c, 0x9b, 0x58, 0x57, 0xe5, 0x91, 0xd6, 0x46, 0x80, 0x47, 0x1c,
0x05, 0x7e, 0x0c, 0x60, 0xcb, 0xf0, 0x78, 0x46, 0xad, 0x1d, 0x8a, 0x4d, 0x5c, 0xe7, 0xac, 0xa2,
0x20, 0x0b, 0x71, 0x75, 0x6c, 0xf5, 0x21, 0xd0, 0x00, 0x2b, 0xf8, 0xb5, 0x02, 0x96, 0xeb, 0xfd,
0x43, 0x46, 0xd6, 0xe5, 0xa5, 0x71, 0x12, 0x3d, 0x60, 0x46, 0xe9, 0xab, 0xdd, 0x4e, 0x65, 0x79,
0x80, 0x02, 0x0d, 0x72, 0x06, 0xef, 0x81, 0x02, 0xf5, 0x9b, 0x98, 0x95, 0xf2, 0xe2, 0x7a, 0x33,
0xbd, 0xee, 0x38, 0x4d, 0x62, 0x1e, 0x22, 0x6e, 0xf2, 0x29, 0xf1, 0x1a, 0xbb, 0xbe, 0x98, 0x55,
0x2c, 0xbe, 0x6b, 0xa1, 0x42, 0x01, 0xa9, 0xfa, 0x08, 0x2c, 0xa5, 0x87, 0x06, 0xb4, 0x00, 0x30,
0xc3, 0x3e, 0x65, 0x25, 0x45, 0xb8, 0x3d, 0x3f, 0x7e, 0x55, 0x45, 0x3d, 0x1e, 0xcf, 0xcb, 0x48,
0xc4, 0x50, 0x0f, 0xb5, 0x7a, 0x06, 0xcc, 0x5d, 0xa3, 0x8e, 0xef, 0xca, 0x33, 0xc2, 0x75, 0x90,
0xb7, 0x8d, 0x56, 0x38, 0x7d, 0xa2, 0x89, 0xb8, 0x6d, 0xb4, 0x30, 0x12, 0x1a, 0xf5, 0x7b, 0x05,
0xcc, 0x6f, 0x92, 0x16, 0xf1, 0x10, 0x66, 0xae, 0x63, 0x33, 0x0c, 0x2f, 0x26, 0x26, 0xd6, 0xf1,
0xd4, 0xc4, 0x3a, 0x92, 0x00, 0xf7, 0xcc, 0xaa, 0xcf, 0xc1, 0xf4, 0x43, 0x1f, 0xfb, 0xc4, 0xb6,
0xe4, 0xbc, 0xbe, 0x90, 0x15, 0xe0, 0xad, 0x00, 0x9e, 0xa8, 0x36, 0x7d, 0x96, 0x8f, 0x00, 0xa9,
0x41, 0x21, 0xa3, 0xfa, 0x77, 0x0e, 0x1c, 0x17, 0x8e, 0x71, 0x7d, 0x78, 0x15, 0xc3, 0x7b, 0xa0,
0x64, 0x3b, 0x2d, 0x62, 0x1b, 0x5c, 0x6e, 0xfa, 0x94, 0xd7, 0xff, 0xe1, 0x6e, 0xc3, 0xa0, 0x98,
0x89, 0x68, 0x0a, 0xfa, 0xba, 0x8c, 0xa6, 0xb4, 0x3d, 0x04, 0x87, 0x86, 0x32, 0xc0, 0x07, 0x60,
0xbe, 0xd9, 0x1b, 0xbb, 0x0c, 0xf3, 0x74, 0x56, 0x98, 0x89, 0x84, 0xe9, 0x2b, 0xf2, 0x04, 0xc9,
0xa4, 0xa3, 0x24, 0x35, 0x7c, 0x07, 0x2c, 0x36, 0xb1, 0x5d, 0x37, 0x6a, 0x4d, 0xbc, 0x83, 0xa9,
0x89, 0x6d, 0x4f, 0xb4, 0x48, 0x41, 0x5f, 0xee, 0x76, 0x2a, 0x8b, 0x9b, 0x49, 0x15, 0x4a, 0x63,
0xe1, 0x4d, 0xb0, 0x52, 0x73, 0x28, 0x75, 0x0e, 0x88, 0x6d, 0x09, 0x3f, 0x21, 0x49, 0x5e, 0x90,
0xfc, 0xa7, 0xdb, 0xa9, 0xac, 0xe8, 0x83, 0x00, 0x68, 0xb0, 0x9d, 0x7a, 0x00, 0x56, 0xb6, 0xf9,
0x4c, 0x61, 0x8e, 0x4f, 0x4d, 0x1c, 0x37, 0x04, 0xac, 0x80, 0x42, 0x1b, 0xd3, 0x5a, 0x50, 0xd4,
0x45, 0xbd, 0xc8, 0xdb, 0xe1, 0x13, 0x2e, 0x40, 0x81, 0x9c, 0x47, 0x62, 0xc7, 0x96, 0x77, 0xd0,
0x26, 0x2b, 0x4d, 0x09, 0xa8, 0x88, 0x64, 0x3b, 0xa9, 0x42, 0x69, 0xac, 0xda, 0xc9, 0x81, 0xd5,
0x21, 0xfd, 0x07, 0xef, 0x80, 0x19, 0x26, 0xff, 0x96, 0x3d, 0x75, 0x22, 0xeb, 0x2e, 0xa4, 0x6d,
0x3c, 0xfd, 0x43, 0x32, 0x14, 0x51, 0x41, 0x07, 0xcc, 0x53, 0x79, 0x04, 0xe1, 0x53, 0xbe, 0x02,
0xe7, 0xb2, 0xb8, 0xfb, 0xb3, 0x13, 0x5f, 0x36, 0xea, 0x25, 0x44, 0x49, 0x7e, 0xf8, 0x08, 0x2c,
0xf5, 0x84, 0x1d, 0xf8, 0x9c, 0x14, 0x3e, 0x2f, 0x66, 0xf9, 0x1c, 0x78, 0x29, 0x7a, 0x49, 0xba,
0x5d, 0xda, 0x4e, 0xd1, 0xa2, 0x3e, 0x47, 0xea, 0x2f, 0x39, 0x30, 0xe2, 0x61, 0x78, 0x05, 0x4b,
0xde, 0xfd, 0xc4, 0x92, 0xf7, 0xee, 0x8b, 0xbf, 0x78, 0x43, 0x97, 0xbe, 0x46, 0x6a, 0xe9, 0x7b,
0xff, 0x25, 0x7c, 0x8c, 0x5e, 0x02, 0xff, 0xcc, 0x81, 0xff, 0x0e, 0x37, 0x8e, 0x97, 0xc2, 0x1b,
0x89, 0x11, 0x7b, 0x29, 0x35, 0x62, 0x4f, 0x8c, 0x41, 0xf1, 0xef, 0x92, 0x98, 0x5a, 0x12, 0x7f,
0x55, 0x40, 0x79, 0x78, 0xde, 0x5e, 0xc1, 0xd2, 0xf8, 0x45, 0x72, 0x69, 0x7c, 0xeb, 0xc5, 0x8b,
0x6c, 0xc8, 0x12, 0x79, 0x6d, 0x54, 0x6d, 0x45, 0xeb, 0xde, 0x18, 0x4f, 0xfe, 0xcf, 0x23, 0x53,
0x25, 0xb6, 0xd3, 0x8c, 0x5f, 0x2d, 0x09, 0xeb, 0x0f, 0x6c, 0xfe, 0xf4, 0xb4, 0xf8, 0xeb, 0x11,
0x14, 0x64, 0x03, 0x4c, 0x37, 0x83, 0xb7, 0x5a, 0x36, 0xf5, 0x95, 0xb1, 0x9e, 0xc8, 0x51, 0x4f,
0x7b, 0xb0, 0x16, 0x48, 0x18, 0x0a, 0xe9, 0xd5, 0xef, 0x14, 0xb0, 0x9e, 0xd5, 0xac, 0xf0, 0x60,
0xc0, 0xf2, 0xf5, 0x12, 0x8b, 0xf5, 0xf8, 0xcb, 0xd8, 0x8f, 0x0a, 0x38, 0x3a, 0x68, 0xc7, 0xe1,
0xe5, 0xcf, 0x17, 0x9b, 0x68, 0x2b, 0x89, 0xca, 0xff, 0x96, 0x90, 0x22, 0xa9, 0x85, 0xa7, 0xc0,
0x4c, 0xc3, 0xb0, 0xeb, 0xbb, 0xe4, 0xcb, 0x70, 0xdf, 0x8e, 0x0a, 0xf0, 0x23, 0x29, 0x47, 0x11,
0x02, 0x5e, 0x05, 0x4b, 0xc2, 0x6e, 0x13, 0xdb, 0x96, 0xd7, 0x10, 0xb9, 0x92, 0x4b, 0x43, 0xf4,
0x1e, 0xdc, 0x4a, 0xe9, 0x51, 0x9f, 0x85, 0xfa, 0x97, 0x02, 0xe0, 0x8b, 0xbc, 0xf3, 0x27, 0x41,
0xd1, 0x70, 0x89, 0x58, 0x3e, 0x83, 0x16, 0x28, 0xea, 0xf3, 0xdd, 0x4e, 0xa5, 0x78, 0x65, 0xe7,
0x7a, 0x20, 0x44, 0xb1, 0x9e, 0x83, 0xc3, 0x27, 0x30, 0x78, 0xea, 0x24, 0x38, 0x74, 0xcc, 0x50,
0xac, 0x87, 0x97, 0xc1, 0x9c, 0xd9, 0xf4, 0x99, 0x87, 0xe9, 0xae, 0xe9, 0xb8, 0x58, 0x8c, 0x8c,
0x19, 0xfd, 0xa8, 0x8c, 0x69, 0x6e, 0xa3, 0x47, 0x87, 0x12, 0x48, 0xa8, 0x01, 0xc0, 0x0b, 0x9e,
0xb9, 0x06, 0xf7, 0x53, 0x10, 0x7e, 0x16, 0xf8, 0x85, 0x6d, 0x47, 0x52, 0xd4, 0x83, 0x50, 0x1f,
0x80, 0x95, 0x5d, 0x4c, 0xdb, 0xc4, 0xc4, 0x57, 0x4c, 0xd3, 0xf1, 0x6d, 0x2f, 0x5c, 0xa3, 0xab,
0xa0, 0x18, 0xc1, 0x64, 0x4f, 0x1c, 0x91, 0xfe, 0x8b, 0x11, 0x17, 0x8a, 0x31, 0x51, 0x13, 0xe6,
0x86, 0x37, 0x61, 0x0e, 0x4c, 0xc7, 0xf4, 0xf9, 0x7d, 0x62, 0xd7, 0x25, 0xf3, 0xb1, 0x10, 0x7d,
0x83, 0xd8, 0xf5, 0xe7, 0x9d, 0xca, 0xac, 0x84, 0xf1, 0x4f, 0x24, 0x80, 0xf0, 0x3a, 0xc8, 0xfb,
0x0c, 0x53, 0xd9, 0x5e, 0x27, 0xb3, 0x8a, 0xf9, 0x0e, 0xc3, 0x34, 0xdc, 0x7c, 0x66, 0x38, 0x33,
0x17, 0x20, 0x41, 0x01, 0xb7, 0x40, 0xc1, 0xe2, 0x97, 0x22, 0xa7, 0xfe, 0xa9, 0x2c, 0xae, 0xde,
0x9f, 0x17, 0x41, 0x19, 0x08, 0x09, 0x0a, 0x58, 0xe0, 0x43, 0xb0, 0xc0, 0x12, 0x29, 0x14, 0xd7,
0x35, 0xc6, 0x26, 0x33, 0x30, 0xf1, 0x3a, 0xec, 0x76, 0x2a, 0x0b, 0x49, 0x15, 0x4a, 0x39, 0x50,
0xab, 0x60, 0xb6, 0x27, 0xc0, 0xec, 0xf9, 0xa7, 0x5f, 0x7d, 0xfc, 0xac, 0x3c, 0xf1, 0xe4, 0x59,
0x79, 0xe2, 0xe9, 0xb3, 0xf2, 0xc4, 0x57, 0xdd, 0xb2, 0xf2, 0xb8, 0x5b, 0x56, 0x9e, 0x74, 0xcb,
0xca, 0xd3, 0x6e, 0x59, 0xf9, 0xad, 0x5b, 0x56, 0xbe, 0xf9, 0xbd, 0x3c, 0x71, 0xb7, 0x3c, 0xfa,
0xff, 0x8c, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x98, 0x4a, 0x24, 0x86, 0xa1, 0x14, 0x00, 0x00,
}
func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) {
@@ -1154,6 +1157,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i
_ = i
var l int
_ = l
if m.BorrowingLimitPercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent))
i--
dAtA[i] = 0x20
}
if m.LendablePercent != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent))
i--
dAtA[i] = 0x18
}
{
size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -1903,6 +1916,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) {
n += 1 + sovGenerated(uint64(m.NominalConcurrencyShares))
l = m.LimitResponse.Size()
n += 1 + l + sovGenerated(uint64(l))
if m.LendablePercent != nil {
n += 1 + sovGenerated(uint64(*m.LendablePercent))
}
if m.BorrowingLimitPercent != nil {
n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent))
}
return n
}
@@ -2258,6 +2277,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string {
s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`,
`NominalConcurrencyShares:` + fmt.Sprintf("%v", this.NominalConcurrencyShares) + `,`,
`LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`,
`LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`,
`BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`,
`}`,
}, "")
return s
@@ -3542,6 +3563,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.LendablePercent = &v
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.BorrowingLimitPercent = &v
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])

View File

@@ -178,6 +178,35 @@ message LimitedPriorityLevelConfiguration {
// `limitResponse` indicates what to do with requests that can not be executed right now
optional LimitResponse limitResponse = 2;
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
optional int32 lendablePercent = 3;
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
optional int32 borrowingLimitPercent = 4;
}
// NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the

View File

@@ -472,6 +472,35 @@ type LimitedPriorityLevelConfiguration struct {
// `limitResponse` indicates what to do with requests that can not be executed right now
LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"`
// `lendablePercent` prescribes the fraction of the level's NominalCL that
// can be borrowed by other priority levels. The value of this
// field must be between 0 and 100, inclusive, and it defaults to 0.
// The number of seats that other levels can borrow from this level, known
// as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.
//
// LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )
//
// +optional
LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"`
// `borrowingLimitPercent`, if present, configures a limit on how many
// seats this priority level can borrow from other priority levels.
// The limit is known as this level's BorrowingConcurrencyLimit
// (BorrowingCL) and is a limit on the total number of seats that this
// level may borrow at any one time.
// This field holds the ratio of that limit to the level's nominal
// concurrency limit. When this field is non-nil, it must hold a
// non-negative integer and the limit is calculated as follows.
//
// BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )
//
// The value of this field can be more than 100, implying that this
// priority level can borrow a number of seats that is greater than
// its own nominal concurrency limit (NominalCL).
// When this field is left `nil`, the limit is effectively infinite.
// +optional
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"`
}
// LimitResponse defines how to handle requests that can not be executed right now.

View File

@@ -114,6 +114,8 @@ var map_LimitedPriorityLevelConfiguration = map[string]string{
"": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?",
"nominalConcurrencyShares": "`nominalConcurrencyShares` (NCS) contributes to the computation of the NominalConcurrencyLimit (NominalCL) of this level. This is the number of execution seats available at this priority level. This is used both for requests dispatched from this priority level as well as requests dispatched from other priority levels borrowing seats from this level. The server's concurrency limit (ServerCL) is divided among the Limited priority levels in proportion to their NCS values:\n\nNominalCL(i) = ceil( ServerCL * NCS(i) / sum_ncs ) sum_ncs = sum[limited priority level k] NCS(k)\n\nBigger numbers mean a larger nominal concurrency limit, at the expense of every other Limited priority level. This field has a default value of 30.",
"limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now",
"lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )",
"borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.",
}
func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string {

View File

@@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse {
func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) {
*out = *in
in.LimitResponse.DeepCopyInto(&out.LimitResponse)
if in.LendablePercent != nil {
in, out := &in.LendablePercent, &out.LendablePercent
*out = new(int32)
**out = **in
}
if in.BorrowingLimitPercent != nil {
in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent
*out = new(int32)
**out = **in
}
return
}

View File

@@ -54,7 +54,9 @@
"handSize": 2,
"queueLengthLimit": 3
}
}
},
"lendablePercent": 3,
"borrowingLimitPercent": 4
}
},
"status": {

View File

@@ -35,6 +35,8 @@ metadata:
spec:
limited:
assuredConcurrencyShares: 1
borrowingLimitPercent: 4
lendablePercent: 3
limitResponse:
queuing:
handSize: 2

View File

@@ -54,7 +54,9 @@
"handSize": 2,
"queueLengthLimit": 3
}
}
},
"lendablePercent": 3,
"borrowingLimitPercent": 4
}
},
"status": {

View File

@@ -35,6 +35,8 @@ metadata:
spec:
limited:
assuredConcurrencyShares: 1
borrowingLimitPercent: 4
lendablePercent: 3
limitResponse:
queuing:
handSize: 2

View File

@@ -54,7 +54,9 @@
"handSize": 2,
"queueLengthLimit": 3
}
}
},
"lendablePercent": 3,
"borrowingLimitPercent": 4
}
},
"status": {

View File

@@ -35,6 +35,8 @@ metadata:
spec:
limited:
assuredConcurrencyShares: 1
borrowingLimitPercent: 4
lendablePercent: 3
limitResponse:
queuing:
handSize: 2

View File

@@ -54,7 +54,9 @@
"handSize": 2,
"queueLengthLimit": 3
}
}
},
"lendablePercent": 3,
"borrowingLimitPercent": 4
}
},
"status": {

View File

@@ -34,6 +34,8 @@ metadata:
uid: uidValue
spec:
limited:
borrowingLimitPercent: 4
lendablePercent: 3
limitResponse:
queuing:
handSize: 2

View File

@@ -23,6 +23,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/authentication/serviceaccount"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/utils/pointer"
)
// The objects that define an apiserver's initial behavior. The
@@ -96,6 +97,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 5,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeReject,
},
@@ -168,6 +170,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 30,
LendablePercent: pointer.Int32(33),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{
@@ -184,6 +187,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 40,
LendablePercent: pointer.Int32(25),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{
@@ -201,6 +205,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 10,
LendablePercent: pointer.Int32(0),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{
@@ -218,6 +223,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 40,
LendablePercent: pointer.Int32(50),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{
@@ -235,6 +241,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 100,
LendablePercent: pointer.Int32(90),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{
@@ -252,6 +259,7 @@ var (
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 20,
LendablePercent: pointer.Int32(50),
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{

View File

@@ -0,0 +1,117 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package bootstrap
import (
"testing"
flowcontrol "k8s.io/api/flowcontrol/v1beta3"
)
func TestBootstrapPriorityLevelConfigurationWithBorrowing(t *testing.T) {
tests := []struct {
name string
nominalSharesExpected int32
lendablePercentexpected int32
}{
{
name: "leader-election",
nominalSharesExpected: 10,
lendablePercentexpected: 0,
},
{
name: "node-high",
nominalSharesExpected: 40,
lendablePercentexpected: 25,
},
{
name: "system",
nominalSharesExpected: 30,
lendablePercentexpected: 33,
},
{
name: "workload-high",
nominalSharesExpected: 40,
lendablePercentexpected: 50,
},
{
name: "workload-low",
nominalSharesExpected: 100,
lendablePercentexpected: 90,
},
{
name: "global-default",
nominalSharesExpected: 20,
lendablePercentexpected: 50,
},
{
name: "catch-all",
nominalSharesExpected: 5,
lendablePercentexpected: 0,
},
}
bootstrapPLs := func() map[string]*flowcontrol.PriorityLevelConfiguration {
list := make([]*flowcontrol.PriorityLevelConfiguration, 0)
list = append(list, MandatoryPriorityLevelConfigurations...)
list = append(list, SuggestedPriorityLevelConfigurations...)
m := map[string]*flowcontrol.PriorityLevelConfiguration{}
for i := range list {
m[list[i].Name] = list[i]
}
return m
}()
for _, test := range tests {
bootstrapPL := bootstrapPLs[test.name]
if bootstrapPL == nil {
t.Errorf("Expected bootstrap PriorityLevelConfiguration %q, but not found in bootstrap configuration", test.name)
continue
}
delete(bootstrapPLs, test.name)
if bootstrapPL.Spec.Type != flowcontrol.PriorityLevelEnablementLimited {
t.Errorf("bootstrap PriorityLevelConfiguration %q is not %q", test.name, flowcontrol.PriorityLevelEnablementLimited)
continue
}
if test.nominalSharesExpected != bootstrapPL.Spec.Limited.NominalConcurrencyShares {
t.Errorf("bootstrap PriorityLevelConfiguration %q: expected NominalConcurrencyShares: %d, but got: %d", test.name, test.nominalSharesExpected, bootstrapPL.Spec.Limited.NominalConcurrencyShares)
}
if test.lendablePercentexpected != *bootstrapPL.Spec.Limited.LendablePercent {
t.Errorf("bootstrap PriorityLevelConfiguration %q: expected NominalConcurrencyShares: %d, but got: %d", test.name, test.lendablePercentexpected, bootstrapPL.Spec.Limited.LendablePercent)
}
if bootstrapPL.Spec.Limited.BorrowingLimitPercent != nil {
t.Errorf("bootstrap PriorityLevelConfiguration %q: expected BorrowingLimitPercent to be nil, but got: %d", test.name, *bootstrapPL.Spec.Limited.BorrowingLimitPercent)
}
}
if len(bootstrapPLs) != 0 {
names := make([]string, 0)
for name, bpl := range bootstrapPLs {
if bpl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt {
t.Logf("bootstrap PriorityLevelConfiguration %q is of %q type, skipped", name, flowcontrol.PriorityLevelConfigurationNameExempt)
continue
}
names = append(names, name)
}
if len(names) != 0 {
t.Errorf("bootstrap PriorityLevelConfiguration objects not accounted by this test: %v", names)
}
}
}

View File

@@ -1112,7 +1112,7 @@ func startAPFController(t *testing.T, stopCh <-chan struct{}, apfConfiguration [
// make sure that apf controller syncs the priority level configuration object we are using in this test.
// read the metrics and ensure the concurrency limit for our priority level is set to the expected value.
pollErr := wait.PollImmediate(100*time.Millisecond, 5*time.Second, func() (done bool, err error) {
if err := gaugeValueMatch("apiserver_flowcontrol_request_concurrency_limit", map[string]string{"priority_level": plName}, plConcurrency); err != nil {
if err := gaugeValueMatch("apiserver_flowcontrol_nominal_limit_seats", map[string]string{"priority_level": plName}, plConcurrency); err != nil {
t.Logf("polling retry - error: %s", err)
return false, nil
}

View File

@@ -177,6 +177,12 @@ type configController struct {
// name to the state for that level. Every name referenced from a
// member of `flowSchemas` has an entry here.
priorityLevelStates map[string]*priorityLevelState
// nominalCLSum is the sum of the nominalCL fields in the priorityLevelState records.
// This can exceed serverConcurrencyLimit because of the deliberate rounding up
// in the computation of the nominalCL values.
// This is tracked because it is an input to the allocation adjustment algorithm.
nominalCLSum int
}
type updateAttempt struct {
@@ -225,6 +231,18 @@ type priorityLevelState struct {
// Periodically smoothed gets replaced with `max(envelope, A*smoothed + (1-A)*envelope)`,
// where A is seatDemandSmoothingCoefficient.
seatDemandStats seatDemandStats
// nominalCL is the nominal concurrency limit configured in the PriorityLevelConfiguration
nominalCL int
// minCL is the nominal limit less the lendable amount
minCL int
//maxCL is the nominal limit plus the amount that may be borrowed
maxCL int
// currentCL is the dynamically derived concurrency limit to impose for now
currentCL int
}
type seatDemandStats struct {
@@ -234,15 +252,6 @@ type seatDemandStats struct {
smoothed float64
}
func newSeatDemandStats(val float64) seatDemandStats {
return seatDemandStats{
avg: val,
stdDev: 0,
highWatermark: val,
smoothed: val,
}
}
func (stats *seatDemandStats) update(obs fq.IntegratorResults) {
stats.avg = obs.Average
stats.stdDev = obs.Deviation
@@ -368,12 +377,74 @@ func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error {
func (cfgCtlr *configController) updateBorrowing() {
cfgCtlr.lock.Lock()
defer cfgCtlr.lock.Unlock()
for _, plState := range cfgCtlr.priorityLevelStates {
cfgCtlr.updateBorrowingLocked(true, cfgCtlr.priorityLevelStates)
}
func (cfgCtlr *configController) updateBorrowingLocked(setCompleters bool, plStates map[string]*priorityLevelState) {
items := make([]allocProblemItem, 0, len(plStates))
plNames := make([]string, 0, len(plStates))
for plName, plState := range plStates {
if plState.pl.Spec.Limited == nil {
continue
}
obs := plState.seatDemandIntegrator.Reset()
plState.seatDemandStats.update(obs)
metrics.NotePriorityLevelConcurrencyAdjustment(plState.pl.Name, plState.seatDemandStats.highWatermark, plState.seatDemandStats.avg, plState.seatDemandStats.stdDev, plState.seatDemandStats.smoothed /* TODO: add the designed rest for borrowing */)
// TODO: updathe CurrentCL as described in https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness#dispatching
// Lower bound on this priority level's adjusted concurreny limit is the lesser of:
// - its seat demamd high watermark over the last adjustment period, and
// - its configured concurrency limit.
// BUT: we do not want this to be lower than the lower bound from configuration.
// See KEP-1040 for a more detailed explanation.
minCurrentCL := math.Max(float64(plState.minCL), math.Min(float64(plState.nominalCL), plState.seatDemandStats.highWatermark))
plNames = append(plNames, plName)
items = append(items, allocProblemItem{
lowerBound: minCurrentCL,
upperBound: float64(plState.maxCL),
target: math.Max(minCurrentCL, plState.seatDemandStats.smoothed),
})
}
if len(items) == 0 && cfgCtlr.nominalCLSum > 0 {
klog.ErrorS(nil, "Impossible: no non-exempt priority levels", "plStates", cfgCtlr.priorityLevelStates)
return
}
allocs, fairFrac, err := computeConcurrencyAllocation(cfgCtlr.nominalCLSum, items)
if err != nil {
klog.ErrorS(err, "Unable to derive new concurrency limits", "plNames", plNames, "items", items)
allocs = make([]float64, len(items))
for idx, plName := range plNames {
plState := plStates[plName]
if plState.pl.Spec.Limited == nil {
continue
}
allocs[idx] = float64(plState.currentCL)
}
}
for idx, plName := range plNames {
plState := plStates[plName]
if plState.pl.Spec.Limited == nil {
continue
}
if setCompleters {
qsCompleter, err := queueSetCompleterForPL(cfgCtlr.queueSetFactory, plState.queues,
plState.pl, cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs,
metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge))
if err != nil {
klog.ErrorS(err, "Inconceivable! Configuration error in existing priority level", "pl", plState.pl)
continue
}
plState.qsCompleter = qsCompleter
}
currentCL := int(math.Round(float64(allocs[idx])))
relChange := relDiff(float64(currentCL), float64(plState.currentCL))
plState.currentCL = currentCL
metrics.NotePriorityLevelConcurrencyAdjustment(plState.pl.Name, plState.seatDemandStats.highWatermark, plState.seatDemandStats.avg, plState.seatDemandStats.stdDev, plState.seatDemandStats.smoothed, float64(items[idx].target), currentCL)
logLevel := klog.Level(4)
if relChange >= 0.05 {
logLevel = 2
}
klog.V(logLevel).InfoS("Update CurrentCL", "plName", plName, "seatDemandHighWatermark", plState.seatDemandStats.highWatermark, "seatDemandAvg", plState.seatDemandStats.avg, "seatDemandStdev", plState.seatDemandStats.stdDev, "seatDemandSmoothed", plState.seatDemandStats.smoothed, "fairFrac", fairFrac, "currentCL", currentCL, "backstop", err != nil)
plState.queues = plState.qsCompleter.Complete(fq.DispatchingConfig{ConcurrencyLimit: currentCL})
}
metrics.SetFairFrac(float64(fairFrac))
}
// runWorker is the logic of the one and only worker goroutine. We
@@ -605,7 +676,9 @@ func (meal *cfgMeal) digestNewPLsLocked(newPLs []*flowcontrol.PriorityLevelConfi
seatDemandRatioedGauge: metrics.ApiserverSeatDemands.NewForLabelValuesSafe(0, 1, []string{pl.Name}),
}
}
qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, state.queues, pl, meal.cfgCtlr.requestWaitLimit, state.reqsGaugePair, state.execSeatsObs, metrics.NewUnionGauge(state.seatDemandIntegrator, state.seatDemandRatioedGauge))
qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, state.queues,
pl, meal.cfgCtlr.requestWaitLimit, state.reqsGaugePair, state.execSeatsObs,
metrics.NewUnionGauge(state.seatDemandIntegrator, state.seatDemandRatioedGauge))
if err != nil {
klog.Warningf("Ignoring PriorityLevelConfiguration object %s because its spec (%s) is broken: %s", pl.Name, fcfmt.Fmt(pl.Spec), err)
continue
@@ -709,7 +782,9 @@ func (meal *cfgMeal) processOldPLsLocked() {
}
}
var err error
plState.qsCompleter, err = queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, plState.queues, plState.pl, meal.cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs, metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge))
plState.qsCompleter, err = queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, plState.queues,
plState.pl, meal.cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs,
metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge))
if err != nil {
// This can not happen because queueSetCompleterForPL already approved this config
panic(fmt.Sprintf("%s from name=%q spec=%s", err, plName, fcfmt.Fmt(plState.pl.Spec)))
@@ -739,30 +814,49 @@ func (meal *cfgMeal) finishQueueSetReconfigsLocked() {
continue
}
limited := plState.pl.Spec.Limited
// The use of math.Ceil here means that the results might sum
// to a little more than serverConcurrencyLimit but the
// difference will be negligible.
concurrencyLimit := int(math.Ceil(float64(meal.cfgCtlr.serverConcurrencyLimit) * float64(plState.pl.Spec.Limited.NominalConcurrencyShares) / meal.shareSum))
metrics.UpdateSharedConcurrencyLimit(plName, concurrencyLimit)
metrics.SetPriorityLevelConfiguration(plName, concurrencyLimit /* TODO: pass min and max once new API is available */, concurrencyLimit, concurrencyLimit)
concurrencyLimit := int(math.Ceil(float64(meal.cfgCtlr.serverConcurrencyLimit) * float64(limited.NominalConcurrencyShares) / meal.shareSum))
var lendableCL, borrowingCL int
if limited.LendablePercent != nil {
lendableCL = int(math.Round(float64(concurrencyLimit) * float64(*limited.LendablePercent) / 100))
}
if limited.BorrowingLimitPercent != nil {
borrowingCL = int(math.Round(float64(concurrencyLimit) * float64(*limited.BorrowingLimitPercent) / 100))
} else {
borrowingCL = meal.cfgCtlr.serverConcurrencyLimit
}
metrics.SetPriorityLevelConfiguration(plName, concurrencyLimit, concurrencyLimit-lendableCL, concurrencyLimit+borrowingCL)
plState.seatDemandRatioedGauge.SetDenominator(float64(concurrencyLimit))
cfgChanged := plState.nominalCL != concurrencyLimit || plState.minCL != concurrencyLimit-lendableCL || plState.maxCL != concurrencyLimit+borrowingCL
plState.nominalCL = concurrencyLimit
plState.minCL = concurrencyLimit - lendableCL
plState.maxCL = concurrencyLimit + borrowingCL
meal.maxExecutingRequests += concurrencyLimit
var waitLimit int
if qCfg := plState.pl.Spec.Limited.LimitResponse.Queuing; qCfg != nil {
if qCfg := limited.LimitResponse.Queuing; qCfg != nil {
waitLimit = int(qCfg.Queues * qCfg.QueueLengthLimit)
}
meal.maxWaitingRequests += waitLimit
if plState.queues == nil {
klog.V(5).Infof("Introducing queues for priority level %q: config=%s, concurrencyLimit=%d, quiescing=%v (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, plState.quiescing, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum)
plState.seatDemandStats = newSeatDemandStats(float64(concurrencyLimit))
// TODO: initialize as described in https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness#dispatching once NominalCL values are implemented
initialCL := concurrencyLimit - lendableCL/2
klog.V(2).Infof("Introducing queues for priority level %q: config=%s, nominalCL=%d, lendableCL=%d, borrowingCL=%d, currentCL=%d, quiescing=%v (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, lendableCL, borrowingCL, initialCL, plState.quiescing, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum)
plState.seatDemandStats = seatDemandStats{}
plState.currentCL = initialCL
} else {
klog.V(5).Infof("Retaining queues for priority level %q: config=%s, concurrencyLimit=%d, quiescing=%v, numPending=%d (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, plState.quiescing, plState.numPending, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum)
logLevel := klog.Level(5)
if cfgChanged {
logLevel = 2
}
plState.queues = plState.qsCompleter.Complete(fq.DispatchingConfig{ConcurrencyLimit: concurrencyLimit})
klog.V(logLevel).Infof("Retaining queues for priority level %q: config=%s, nominalCL=%d, lendableCL=%d, borrowingCL=%d, currentCL=%d, quiescing=%v, numPending=%d (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, lendableCL, borrowingCL, plState.currentCL, plState.quiescing, plState.numPending, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum)
}
}
meal.cfgCtlr.nominalCLSum = meal.maxExecutingRequests
meal.cfgCtlr.updateBorrowingLocked(false, meal.newPLStates)
}
// queueSetCompleterForPL returns an appropriate QueueSetCompleter for the
// given priority level configuration. Returns nil if that config
@@ -847,7 +941,9 @@ func (meal *cfgMeal) imaginePL(proto *flowcontrol.PriorityLevelConfiguration, re
execSeatsObs := meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues)
seatDemandIntegrator := fq.NewNamedIntegrator(meal.cfgCtlr.clock, proto.Name)
seatDemandRatioedGauge := metrics.ApiserverSeatDemands.NewForLabelValuesSafe(0, 1, []string{proto.Name})
qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto, requestWaitLimit, reqsGaugePair, execSeatsObs, metrics.NewUnionGauge(seatDemandIntegrator, seatDemandRatioedGauge))
qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto,
requestWaitLimit, reqsGaugePair, execSeatsObs,
metrics.NewUnionGauge(seatDemandIntegrator, seatDemandRatioedGauge))
if err != nil {
// This can not happen because proto is one of the mandatory
// objects and these are not erroneous
@@ -1002,3 +1098,12 @@ func hashFlowID(fsName, fDistinguisher string) uint64 {
hash.Sum(sum[:0])
return binary.LittleEndian.Uint64(sum[:8])
}
func relDiff(x, y float64) float64 {
diff := math.Abs(x - y)
den := math.Max(math.Abs(x), math.Abs(y))
if den == 0 {
return 0
}
return diff / den
}

View File

@@ -0,0 +1,251 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package flowcontrol
import (
"context"
"fmt"
"sync"
"testing"
"time"
flowcontrol "k8s.io/api/flowcontrol/v1beta3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/endpoints/request"
fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing"
"k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock"
fqs "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset"
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request"
"k8s.io/client-go/informers"
clientsetfake "k8s.io/client-go/kubernetes/fake"
)
type borrowingTestConstraints struct {
lendable, borrowing int32
}
// TestBorrowing tests borrowing of concurrency between priority levels.
// It runs two scenarios, one where the borrowing hits the limit on
// lendable concurrency and one where the borrowing hits the limit on
// borrowing of concurrency.
// Both scenarios are the same except for the limits.
// The test defines two priority levels, identified as "flows" 0 and 1.
// Both priority levels have a nominal concurrency limit of 12.
// The test maintains 24 concurrent clients for priority level 0
// and 6 for level 1,
// using an exec func that simply sleeps for 250 ms, for
// 25 seconds. The first 10 seconds of behavior are ignored, allowing
// the borrowing to start at any point during that time. The test
// continues for another 15 seconds, and checks that the delivered
// concurrency is about 16 for flow 0 and 6 for flow 1.
func TestBorrowing(t *testing.T) {
clientsPerFlow := [2]int{24, 6}
metrics.Register()
for _, testCase := range []struct {
name string
constraints []borrowingTestConstraints
}{
{
name: "lendable-limited",
constraints: []borrowingTestConstraints{
{lendable: 50, borrowing: 67},
{lendable: 33, borrowing: 50},
}},
{
name: "borrowing-limited",
constraints: []borrowingTestConstraints{
{lendable: 50, borrowing: 33},
{lendable: 67, borrowing: 50},
}},
} {
t.Run(testCase.name, func(t *testing.T) {
fsObjs := make([]*flowcontrol.FlowSchema, 2)
plcObjs := make([]*flowcontrol.PriorityLevelConfiguration, 2)
usernames := make([]string, 2)
cfgObjs := []runtime.Object{}
for flow := 0; flow < 2; flow++ {
usernames[flow] = fmt.Sprintf("test-user%d", flow)
plName := fmt.Sprintf("test-pl%d", flow)
fsObjs[flow] = &flowcontrol.FlowSchema{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("test-fs%d", flow),
},
Spec: flowcontrol.FlowSchemaSpec{
MatchingPrecedence: 100,
PriorityLevelConfiguration: flowcontrol.PriorityLevelConfigurationReference{
Name: plName,
},
DistinguisherMethod: &flowcontrol.FlowDistinguisherMethod{
Type: flowcontrol.FlowDistinguisherMethodByUserType,
},
Rules: []flowcontrol.PolicyRulesWithSubjects{{
Subjects: []flowcontrol.Subject{{
Kind: flowcontrol.SubjectKindUser,
User: &flowcontrol.UserSubject{Name: usernames[flow]},
}},
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
Verbs: []string{"*"},
NonResourceURLs: []string{"*"},
}},
}},
},
}
plcObjs[flow] = &flowcontrol.PriorityLevelConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: plName,
},
Spec: flowcontrol.PriorityLevelConfigurationSpec{
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: 100,
LendablePercent: &testCase.constraints[flow].lendable,
BorrowingLimitPercent: &testCase.constraints[flow].borrowing,
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{
Queues: 10,
HandSize: 2,
QueueLengthLimit: 10,
},
},
},
},
}
cfgObjs = append(cfgObjs, fsObjs[flow], plcObjs[flow])
}
clientset := clientsetfake.NewSimpleClientset(cfgObjs...)
informerFactory := informers.NewSharedInformerFactory(clientset, time.Second)
flowcontrolClient := clientset.FlowcontrolV1beta3()
clk := eventclock.Real{}
controller := newTestableController(TestableConfig{
Name: "Controller",
Clock: clk,
AsFieldManager: ConfigConsumerAsFieldManager,
FoundToDangling: func(found bool) bool { return !found },
InformerFactory: informerFactory,
FlowcontrolClient: flowcontrolClient,
ServerConcurrencyLimit: 24,
RequestWaitLimit: time.Minute,
ReqsGaugeVec: metrics.PriorityLevelConcurrencyGaugeVec,
ExecSeatsGaugeVec: metrics.PriorityLevelExecutionSeatsGaugeVec,
QueueSetFactory: fqs.NewQueueSetFactory(clk),
})
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Second)
stopCh := ctx.Done()
controllerCompletionCh := make(chan error)
informerFactory.Start(stopCh)
status := informerFactory.WaitForCacheSync(ctx.Done())
if names := unsynced(status); len(names) > 0 {
t.Fatalf("WaitForCacheSync did not successfully complete, resources=%#v", names)
}
go func() {
controllerCompletionCh <- controller.Run(stopCh)
}()
// ensure that the controller has run its first loop.
err := wait.PollImmediate(100*time.Millisecond, 5*time.Second, func() (done bool, err error) {
return controller.hasPriorityLevelState(plcObjs[0].Name), nil
})
if err != nil {
t.Errorf("expected the controller to reconcile the priority level configuration object: %s, error: %s", plcObjs[0].Name, err)
}
concIntegrators := make([]fq.Integrator, 2)
reqInfo := &request.RequestInfo{
IsResourceRequest: false,
Path: "/foobar",
Verb: "GET",
}
noteFn := func(fs *flowcontrol.FlowSchema, plc *flowcontrol.PriorityLevelConfiguration, fd string) {}
workEstr := func() fcrequest.WorkEstimate { return fcrequest.WorkEstimate{InitialSeats: 1} }
qnf := fq.QueueNoteFn(func(bool) {})
var startWG sync.WaitGroup
startWG.Add(clientsPerFlow[0] + clientsPerFlow[1])
// Launch 20 client threads for each flow
for flow := 0; flow < 2; flow++ {
username := usernames[flow]
flowUser := testUser{name: username}
rd := RequestDigest{
RequestInfo: reqInfo,
User: flowUser,
}
concIntegrator := fq.NewNamedIntegrator(clk, username)
concIntegrators[flow] = concIntegrator
exec := func() {
concIntegrator.Inc()
clk.Sleep(250 * time.Millisecond)
concIntegrator.Dec()
}
nThreads := clientsPerFlow[flow]
for thread := 0; thread < nThreads; thread++ {
go func() {
startWG.Done()
wait.Until(func() { controller.Handle(ctx, rd, noteFn, workEstr, qnf, exec) }, 0, ctx.Done())
}()
}
}
startWG.Wait()
// Make sure the controller has had time to sense the load and adjust
clk.Sleep(10 * time.Second)
// Start the stats that matter from now
for _, ci := range concIntegrators {
ci.Reset()
}
// Run for 15 seconds
clk.Sleep(15 * time.Second)
// Collect the delivered concurrency stats
results0 := concIntegrators[0].Reset()
results1 := concIntegrators[1].Reset()
// shut down all the async stuff
cancel()
// Do the checking
t.Log("waiting for the controller Run function to shutdown gracefully")
controllerErr := <-controllerCompletionCh
close(controllerCompletionCh)
if controllerErr != nil {
t.Errorf("expected nil error from controller Run function, but got: %#v", controllerErr)
}
if results0.Average < 15.5 || results0.Average > 16.1 {
t.Errorf("Flow 0 got average concurrency of %v but expected about 16", results0.Average)
} else {
t.Logf("Flow 0 got average concurrency of %v and expected about 16", results0.Average)
}
if results1.Average < 5.5 || results1.Average > 6.1 {
t.Errorf("Flow 1 got average concurrency of %v but expected about 6", results1.Average)
} else {
t.Logf("Flow 1 got average concurrency of %v and expected about 6", results1.Average)
}
})
}
}
type testUser struct{ name string }
func (tu testUser) GetName() string { return tu.name }
func (tu testUser) GetUID() string { return tu.name }
func (tu testUser) GetGroups() []string { return []string{user.AllAuthenticated} }
func (tu testUser) GetExtra() map[string][]string { return map[string][]string{} }

View File

@@ -1527,12 +1527,9 @@ func newExecSeatsGauge(clk clock.PassiveClock) metrics.RatioedGauge {
func float64close(x, y float64) bool {
x0 := float64NaNTo0(x)
y0 := float64NaNTo0(y)
diff := math.Abs(x - y)
diff := math.Abs(x0 - y0)
den := math.Max(math.Abs(x0), math.Abs(y0))
if den == 0 {
return diff < 1e-10
}
return diff/den < 1e-10
return den == 0 || diff/den < 1e-10
}
func uint64max(a, b uint64) uint64 {

View File

@@ -529,11 +529,6 @@ func AddRequestConcurrencyInUse(priorityLevel, flowSchema string, delta int) {
apiserverRequestConcurrencyInUse.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta))
}
// UpdateSharedConcurrencyLimit updates the value for the concurrency limit in flow control
func UpdateSharedConcurrencyLimit(priorityLevel string, limit int) {
apiserverRequestConcurrencyLimit.WithLabelValues(priorityLevel).Set(float64(limit))
}
// AddReject increments the # of rejected requests for flow control
func AddReject(ctx context.Context, priorityLevel, flowSchema, reason string) {
apiserverRejectedRequestsTotal.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, reason).Add(1)
@@ -585,19 +580,19 @@ func AddDispatchWithNoAccommodation(priorityLevel, flowSchema string) {
}
func SetPriorityLevelConfiguration(priorityLevel string, nominalCL, minCL, maxCL int) {
apiserverRequestConcurrencyLimit.WithLabelValues(priorityLevel).Set(float64(nominalCL))
apiserverNominalConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(nominalCL))
apiserverMinimumConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(minCL))
apiserverMaximumConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(maxCL))
}
func NotePriorityLevelConcurrencyAdjustment(priorityLevel string, seatDemandHWM, seatDemandAvg, seatDemandStdev, seatDemandSmoothed float64 /* TODO: seatDemandTarget float64, currentCL int */) {
func NotePriorityLevelConcurrencyAdjustment(priorityLevel string, seatDemandHWM, seatDemandAvg, seatDemandStdev, seatDemandSmoothed, seatDemandTarget float64, currentCL int) {
apiserverSeatDemandHighWatermarks.WithLabelValues(priorityLevel).Set(seatDemandHWM)
apiserverSeatDemandAverages.WithLabelValues(priorityLevel).Set(seatDemandAvg)
apiserverSeatDemandStandardDeviations.WithLabelValues(priorityLevel).Set(seatDemandStdev)
apiserverSeatDemandSmootheds.WithLabelValues(priorityLevel).Set(seatDemandSmoothed)
// TODO: the following once new API is available
// apiserverSeatDemandTargets.WithLabelValues(priorityLevel).Set(seatDemandTarget)
// apiserverCurrentConcurrencyLimits.WithLabelValues(priorityLevel).Set(currentCL)
apiserverSeatDemandTargets.WithLabelValues(priorityLevel).Set(seatDemandTarget)
apiserverCurrentConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(currentCL))
}
func SetFairFrac(fairFrac float64) {

View File

@@ -23,6 +23,8 @@ package v1alpha1
type LimitedPriorityLevelConfigurationApplyConfiguration struct {
AssuredConcurrencyShares *int32 `json:"assuredConcurrencyShares,omitempty"`
LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"`
}
// LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with
@@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse(
b.LimitResponse = value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}
// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.BorrowingLimitPercent = &value
return b
}

View File

@@ -23,6 +23,8 @@ package v1beta1
type LimitedPriorityLevelConfigurationApplyConfiguration struct {
AssuredConcurrencyShares *int32 `json:"assuredConcurrencyShares,omitempty"`
LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"`
}
// LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with
@@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse(
b.LimitResponse = value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}
// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.BorrowingLimitPercent = &value
return b
}

View File

@@ -23,6 +23,8 @@ package v1beta2
type LimitedPriorityLevelConfigurationApplyConfiguration struct {
AssuredConcurrencyShares *int32 `json:"assuredConcurrencyShares,omitempty"`
LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"`
}
// LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with
@@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse(
b.LimitResponse = value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}
// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.BorrowingLimitPercent = &value
return b
}

View File

@@ -23,6 +23,8 @@ package v1beta3
type LimitedPriorityLevelConfigurationApplyConfiguration struct {
NominalConcurrencyShares *int32 `json:"nominalConcurrencyShares,omitempty"`
LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"`
LendablePercent *int32 `json:"lendablePercent,omitempty"`
BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"`
}
// LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with
@@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse(
b.LimitResponse = value
return b
}
// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LendablePercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.LendablePercent = &value
return b
}
// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call.
func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration {
b.BorrowingLimitPercent = &value
return b
}

View File

@@ -8608,6 +8608,12 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: numeric
default: 0
- name: borrowingLimitPercent
type:
scalar: numeric
- name: lendablePercent
type:
scalar: numeric
- name: limitResponse
type:
namedType: io.k8s.api.flowcontrol.v1alpha1.LimitResponse
@@ -8916,6 +8922,12 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: numeric
default: 0
- name: borrowingLimitPercent
type:
scalar: numeric
- name: lendablePercent
type:
scalar: numeric
- name: limitResponse
type:
namedType: io.k8s.api.flowcontrol.v1beta1.LimitResponse
@@ -9224,6 +9236,12 @@ var schemaYAML = typed.YAMLObject(`types:
type:
scalar: numeric
default: 0
- name: borrowingLimitPercent
type:
scalar: numeric
- name: lendablePercent
type:
scalar: numeric
- name: limitResponse
type:
namedType: io.k8s.api.flowcontrol.v1beta2.LimitResponse
@@ -9528,6 +9546,12 @@ var schemaYAML = typed.YAMLObject(`types:
- name: io.k8s.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration
map:
fields:
- name: borrowingLimitPercent
type:
scalar: numeric
- name: lendablePercent
type:
scalar: numeric
- name: limitResponse
type:
namedType: io.k8s.api.flowcontrol.v1beta3.LimitResponse

View File

@@ -43,7 +43,7 @@ import (
)
const (
requestConcurrencyLimitMetricName = "apiserver_flowcontrol_request_concurrency_limit"
nominalConcurrencyLimitMetricName = "apiserver_flowcontrol_nominal_limit_seats"
priorityLevelLabelName = "priority_level"
)
@@ -146,7 +146,7 @@ var _ = SIGDescribe("API priority and fairness", func() {
ginkgo.By("getting request concurrency from metrics")
for i := range clients {
realConcurrency, err := getPriorityLevelConcurrency(f.ClientSet, clients[i].priorityLevelName)
realConcurrency, err := getPriorityLevelNominalConcurrency(f.ClientSet, clients[i].priorityLevelName)
framework.ExpectNoError(err)
clients[i].concurrency = int32(float64(realConcurrency) * clients[i].concurrencyMultiplier)
if clients[i].concurrency < 1 {
@@ -219,7 +219,7 @@ var _ = SIGDescribe("API priority and fairness", func() {
}
framework.Logf("getting real concurrency")
realConcurrency, err := getPriorityLevelConcurrency(f.ClientSet, priorityLevelName)
realConcurrency, err := getPriorityLevelNominalConcurrency(f.ClientSet, priorityLevelName)
framework.ExpectNoError(err)
for i := range clients {
clients[i].concurrency = int32(float64(realConcurrency) * clients[i].concurrencyMultiplier)
@@ -280,7 +280,7 @@ func createPriorityLevel(f *framework.Framework, priorityLevelName string, nomin
}
}
func getPriorityLevelConcurrency(c clientset.Interface, priorityLevelName string) (int32, error) {
func getPriorityLevelNominalConcurrency(c clientset.Interface, priorityLevelName string) (int32, error) {
resp, err := c.CoreV1().RESTClient().Get().RequestURI("/metrics").DoRaw(context.TODO())
if err != nil {
return 0, err
@@ -299,7 +299,7 @@ func getPriorityLevelConcurrency(c clientset.Interface, priorityLevelName string
return 0, err
}
for _, metric := range v {
if string(metric.Metric[model.MetricNameLabel]) != requestConcurrencyLimitMetricName {
if string(metric.Metric[model.MetricNameLabel]) != nominalConcurrencyLimitMetricName {
continue
}
if string(metric.Metric[priorityLevelLabelName]) != priorityLevelName {
@@ -376,7 +376,7 @@ func waitForSteadyState(f *framework.Framework, flowSchemaName string, priorityL
// hasn't been achieved.
return false, nil
}
_, err = getPriorityLevelConcurrency(f.ClientSet, priorityLevelName)
_, err = getPriorityLevelNominalConcurrency(f.ClientSet, priorityLevelName)
if err != nil {
if err == errPriorityLevelNotFound {
return false, nil

View File

@@ -41,7 +41,7 @@ import (
)
const (
sharedConcurrencyMetricsName = "apiserver_flowcontrol_request_concurrency_limit"
nominalConcurrencyMetricsName = "apiserver_flowcontrol_nominal_limit_seats"
dispatchedRequestCountMetricsName = "apiserver_flowcontrol_dispatched_requests_total"
rejectedRequestCountMetricsName = "apiserver_flowcontrol_rejected_requests_total"
labelPriorityLevel = "priority_level"
@@ -84,16 +84,16 @@ func TestPriorityLevelIsolation(t *testing.T) {
t.Error(err)
}
sharedConcurrency, err := getSharedConcurrencyOfPriorityLevel(loopbackClient)
nominalConcurrency, err := getNominalConcurrencyOfPriorityLevel(loopbackClient)
if err != nil {
t.Error(err)
}
if 1 != sharedConcurrency[priorityLevelNoxu1.Name] {
t.Errorf("unexpected shared concurrency %v instead of %v", sharedConcurrency[priorityLevelNoxu1.Name], 1)
if 1 != nominalConcurrency[priorityLevelNoxu1.Name] {
t.Errorf("unexpected shared concurrency %v instead of %v", nominalConcurrency[priorityLevelNoxu1.Name], 1)
}
if 1 != sharedConcurrency[priorityLevelNoxu2.Name] {
t.Errorf("unexpected shared concurrency %v instead of %v", sharedConcurrency[priorityLevelNoxu2.Name], 1)
if 1 != nominalConcurrency[priorityLevelNoxu2.Name] {
t.Errorf("unexpected shared concurrency %v instead of %v", nominalConcurrency[priorityLevelNoxu2.Name], 1)
}
stopCh := make(chan struct{})
@@ -164,7 +164,7 @@ func getMetrics(c clientset.Interface) (string, error) {
return string(resp), err
}
func getSharedConcurrencyOfPriorityLevel(c clientset.Interface) (map[string]int, error) {
func getNominalConcurrencyOfPriorityLevel(c clientset.Interface) (map[string]int, error) {
resp, err := getMetrics(c)
if err != nil {
return nil, err
@@ -188,7 +188,7 @@ func getSharedConcurrencyOfPriorityLevel(c clientset.Interface) (map[string]int,
}
for _, metric := range v {
switch name := string(metric.Metric[model.MetricNameLabel]); name {
case sharedConcurrencyMetricsName:
case nominalConcurrencyMetricsName:
concurrency[string(metric.Metric[labelPriorityLevel])] = int(metric.Value)
}
}
@@ -230,6 +230,7 @@ func getRequestCountOfPriorityLevel(c clientset.Interface) (map[string]int, map[
}
func createPriorityLevelAndBindingFlowSchemaForUser(c clientset.Interface, username string, concurrencyShares, queuelength int) (*flowcontrol.PriorityLevelConfiguration, *flowcontrol.FlowSchema, error) {
i0 := int32(0)
pl, err := c.FlowcontrolV1beta3().PriorityLevelConfigurations().Create(context.Background(), &flowcontrol.PriorityLevelConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: username,
@@ -238,6 +239,7 @@ func createPriorityLevelAndBindingFlowSchemaForUser(c clientset.Interface, usern
Type: flowcontrol.PriorityLevelEnablementLimited,
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
NominalConcurrencyShares: int32(concurrencyShares),
BorrowingLimitPercent: &i0,
LimitResponse: flowcontrol.LimitResponse{
Type: flowcontrol.LimitResponseTypeQueue,
Queuing: &flowcontrol.QueuingConfiguration{

View File

@@ -41,7 +41,7 @@ import (
)
const (
requestConcurrencyLimitMetricsName = "apiserver_flowcontrol_request_concurrency_limit"
nominalConcurrencyLimitMetricsName = "apiserver_flowcontrol_nominal_limit_seats"
requestExecutionSecondsSumName = "apiserver_flowcontrol_request_execution_seconds_sum"
requestExecutionSecondsCountName = "apiserver_flowcontrol_request_execution_seconds_count"
priorityLevelSeatUtilSumName = "apiserver_flowcontrol_priority_level_seat_utilization_sum"
@@ -350,7 +350,7 @@ func getRequestMetricsSnapshot(c clientset.Interface) (metricSnapshot, error) {
entry.seatUtil.Sum = float64(metric.Value)
case priorityLevelSeatUtilCountName:
entry.seatUtil.Count = int(metric.Value)
case requestConcurrencyLimitMetricsName:
case nominalConcurrencyLimitMetricsName:
entry.availableSeats = int(metric.Value)
}
snapshot[plLabel] = entry