From c016f5ddff49a9b85dcee6b49b4524416c4508ee Mon Sep 17 00:00:00 2001 From: Pedro Soares Date: Fri, 10 May 2024 11:10:55 -0300 Subject: [PATCH] fix(scheduler): optional downThreshold (#619) Many clients forget to update downThreshold or simply do not care how maestro uses it for downscale. To reduce their cognitive load, we can make the parameter optional and if not set always downscale (0.99) --- docs/tutorials/Autoscaling.md | 4 +- .../handlers/requestadapters/schedulers.go | 6 +- .../requestadapters/schedulers_test.go | 17 +- .../core/entities/autoscaling/autoscaling.go | 7 +- .../entities/autoscaling/autoscaling_test.go | 14 +- .../policies/roomoccupancy/policy.go | 6 +- .../policies/roomoccupancy/policy_test.go | 16 +- .../schedulers/patch/patch_scheduler_test.go | 18 +- pkg/api/v1/messages.pb.go | 155 +++++++++--------- proto/api/v1/messages.proto | 2 +- 10 files changed, 136 insertions(+), 109 deletions(-) diff --git a/docs/tutorials/Autoscaling.md b/docs/tutorials/Autoscaling.md index d00a0c21c..188e27449 100644 --- a/docs/tutorials/Autoscaling.md +++ b/docs/tutorials/Autoscaling.md @@ -121,8 +121,8 @@ So basically Maestro will constantly try to maintain a certain percentage of roo actual room occupancy rate (number of rooms in **occupied** state). #### Room Occupancy Policy Parameters -- **readyTarget** [float]: The percentage (in decimal value) of rooms that Maestro should try to keep in **ready** state, must be a value between 0.1 and 0.9. -- **downThreshold** [float]: It adjusts how often maestro scale down Game Rooms, where 0.99 means that maestro will always scale down a Game Room when it is free (respecting the readyTarget), and 0 means that maestro will never scale down. Must be a value between 0 and 0.99. +- **readyTarget** [float]: The percentage (in decimal value) of rooms that Maestro should try to keep in **ready** state, must be a value greater than 0 and less than 1. +- **downThreshold** [float]: It adjusts how often maestro scale down Game Rooms, where 0.99 means that maestro will always scale down a Game Room when it is free (respecting the readyTarget), and a value close to 0 means that maestro will almost never scale down. Must be a value greater than 0 and less than 1. #### Example diff --git a/internal/api/handlers/requestadapters/schedulers.go b/internal/api/handlers/requestadapters/schedulers.go index 64c87233b..ce4f5e2ce 100644 --- a/internal/api/handlers/requestadapters/schedulers.go +++ b/internal/api/handlers/requestadapters/schedulers.go @@ -372,6 +372,9 @@ func fromApiRoomOccupancyPolicyToEntity(roomOccupancy *api.RoomOccupancy) *autos roomOccupancyParam.ReadyTarget = float64(readyTarget) downThreshold := roomOccupancy.GetDownThreshold() + if downThreshold == 0 { + downThreshold = autoscaling.DefaultDownThreshold + } roomOccupancyParam.DownThreshold = float64(downThreshold) return roomOccupancyParam @@ -538,9 +541,10 @@ func getRoomOccupancy(roomOccupancyParameters *autoscaling.RoomOccupancyParams) if roomOccupancyParameters == nil { return nil } + downThresholdVal := float32(roomOccupancyParameters.DownThreshold) return &api.RoomOccupancy{ ReadyTarget: float32(roomOccupancyParameters.ReadyTarget), - DownThreshold: float32(roomOccupancyParameters.DownThreshold), + DownThreshold: &downThresholdVal, } } diff --git a/internal/api/handlers/requestadapters/schedulers_test.go b/internal/api/handlers/requestadapters/schedulers_test.go index 331dc41c6..82936588c 100644 --- a/internal/api/handlers/requestadapters/schedulers_test.go +++ b/internal/api/handlers/requestadapters/schedulers_test.go @@ -343,7 +343,7 @@ func TestFromApiPatchSchedulerRequestToChangeMap(t *testing.T) { Parameters: &api.PolicyParameters{ RoomOccupancy: &api.RoomOccupancy{ ReadyTarget: genericFloat32, - DownThreshold: genericFloat32, + DownThreshold: &genericFloat32, }, }, }, @@ -380,7 +380,7 @@ func TestFromApiPatchSchedulerRequestToChangeMap(t *testing.T) { Parameters: &api.PolicyParameters{ RoomOccupancy: &api.RoomOccupancy{ ReadyTarget: genericFloat32, - DownThreshold: genericFloat32, + DownThreshold: &genericFloat32, }, }, }, @@ -645,7 +645,8 @@ func TestFromApiCreateSchedulerRequestToEntity(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(autoscaling.DefaultDownThreshold), }, }, }, @@ -1299,7 +1300,8 @@ func TestFromApiNewSchedulerVersionRequestToEntity(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(autoscaling.DefaultDownThreshold), }, }, }, @@ -1363,6 +1365,7 @@ func TestFromEntitySchedulerToResponse(t *testing.T) { genericValidVersion := "v1.0.0" genericStringList := []string{"some-value", "another-value"} genericTime := time.Now() + genericFloat32 := float32(0.3) testCases := []struct { Title string @@ -1441,7 +1444,8 @@ func TestFromEntitySchedulerToResponse(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: 0.3, + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, @@ -1532,7 +1536,8 @@ func TestFromEntitySchedulerToResponse(t *testing.T) { Type: "roomOccupancy", Parameters: &api.PolicyParameters{ RoomOccupancy: &api.RoomOccupancy{ - ReadyTarget: float32(0.3), + ReadyTarget: genericFloat32, + DownThreshold: &genericFloat32, }, }, }, diff --git a/internal/core/entities/autoscaling/autoscaling.go b/internal/core/entities/autoscaling/autoscaling.go index d10ff1697..16f37fdaa 100644 --- a/internal/core/entities/autoscaling/autoscaling.go +++ b/internal/core/entities/autoscaling/autoscaling.go @@ -30,7 +30,8 @@ type PolicyType string const ( // RoomOccupancy is an implemented policy in maestro autoscaler, // it uses the number of occupied rooms and a ready rooms target percentage to calculate the desired number of rooms in a scheduler. - RoomOccupancy PolicyType = "roomOccupancy" + RoomOccupancy PolicyType = "roomOccupancy" + DefaultDownThreshold float32 = 0.99 ) // Autoscaling represents the autoscaling configuration for a scheduler. @@ -85,7 +86,7 @@ type PolicyParameters struct { // RoomOccupancyParams represents the parameters accepted by rooms occupancy autoscaling properties. type RoomOccupancyParams struct { // ReadyTarget indicates the target percentage of ready rooms a scheduler should maintain. - ReadyTarget float64 `validate:"gt=0,lte=0.9"` + ReadyTarget float64 `validate:"gt=0,lt=1"` // DownThreshold indicates the percentage of occupied rooms a scheduler should have to trigger a downscale event. - DownThreshold float64 `validate:"gte=0,lte=0.99"` + DownThreshold float64 `validate:"gt=0,lt=1"` } diff --git a/internal/core/entities/autoscaling/autoscaling_test.go b/internal/core/entities/autoscaling/autoscaling_test.go index 0d1e51034..6332cdada 100644 --- a/internal/core/entities/autoscaling/autoscaling_test.go +++ b/internal/core/entities/autoscaling/autoscaling_test.go @@ -95,13 +95,21 @@ func TestNewAutoscaling(t *testing.T) { validationErrs = err.(validator.ValidationErrors) assert.Equal(t, "RoomOccupancy must not be nil for RoomOccupancy policy type", validationErrs[0].Translate(translator)) - _, err = NewAutoscaling(true, 1, 10, 10, Policy{Type: "roomOccupancy", Parameters: PolicyParameters{RoomOccupancy: &RoomOccupancyParams{ReadyTarget: 0.0}}}) + _, err = NewAutoscaling(true, 1, 10, 10, Policy{Type: "roomOccupancy", Parameters: PolicyParameters{RoomOccupancy: &RoomOccupancyParams{ReadyTarget: 0.0, DownThreshold: 0.1}}}) validationErrs = err.(validator.ValidationErrors) assert.Equal(t, "ReadyTarget must be greater than 0", validationErrs[0].Translate(translator)) - _, err = NewAutoscaling(true, 1, 10, 10, Policy{Type: "roomOccupancy", Parameters: PolicyParameters{RoomOccupancy: &RoomOccupancyParams{ReadyTarget: 0.91}}}) + _, err = NewAutoscaling(true, 1, 10, 10, Policy{Type: "roomOccupancy", Parameters: PolicyParameters{RoomOccupancy: &RoomOccupancyParams{ReadyTarget: 1, DownThreshold: 0.1}}}) validationErrs = err.(validator.ValidationErrors) - assert.Equal(t, "ReadyTarget must be 0.9 or less", validationErrs[0].Translate(translator)) + assert.Equal(t, "ReadyTarget must be less than 1", validationErrs[0].Translate(translator)) + + _, err = NewAutoscaling(true, 1, 10, 10, Policy{Type: "roomOccupancy", Parameters: PolicyParameters{RoomOccupancy: &RoomOccupancyParams{ReadyTarget: 0.5, DownThreshold: 0}}}) + validationErrs = err.(validator.ValidationErrors) + assert.Equal(t, "DownThreshold must be greater than 0", validationErrs[0].Translate(translator)) + + _, err = NewAutoscaling(true, 1, 10, 10, Policy{Type: "roomOccupancy", Parameters: PolicyParameters{RoomOccupancy: &RoomOccupancyParams{ReadyTarget: 0.5, DownThreshold: 1}}}) + validationErrs = err.(validator.ValidationErrors) + assert.Equal(t, "DownThreshold must be less than 1", validationErrs[0].Translate(translator)) }) }) diff --git a/internal/core/services/autoscaler/policies/roomoccupancy/policy.go b/internal/core/services/autoscaler/policies/roomoccupancy/policy.go index 8e5786aa2..700ae873e 100644 --- a/internal/core/services/autoscaler/policies/roomoccupancy/policy.go +++ b/internal/core/services/autoscaler/policies/roomoccupancy/policy.go @@ -85,7 +85,7 @@ func (p *Policy) CalculateDesiredNumberOfRooms(policyParameters autoscaling.Poli readyTarget := policyParameters.RoomOccupancy.ReadyTarget if readyTarget >= float64(1) || readyTarget <= 0 { - return -1, errors.New("Ready target must be between 0 and 1") + return -1, errors.New("ready target must be greater than 0 and less than 1") } if _, ok := currentState[OccupiedRoomsKey].(int); !ok { @@ -105,12 +105,12 @@ func (p *Policy) CanDownscale(policyParameters autoscaling.PolicyParameters, cur downThreshold := policyParameters.RoomOccupancy.DownThreshold if downThreshold >= float64(1) || downThreshold <= 0 { - return false, errors.New("Downscale threshold must be between 0 and 1") + return false, errors.New("downscale threshold must be greater than 0 and less than 1") } readyTarget := policyParameters.RoomOccupancy.ReadyTarget if readyTarget >= float64(1) || readyTarget <= 0 { - return false, errors.New("Ready target must be between 0 and 1") + return false, errors.New("ready target must be greater than 0 and less than 1") } readyRooms, ok := currentState[ReadyRoomsKey].(int) diff --git a/internal/core/services/autoscaler/policies/roomoccupancy/policy_test.go b/internal/core/services/autoscaler/policies/roomoccupancy/policy_test.go index f5f2e9308..2009af387 100644 --- a/internal/core/services/autoscaler/policies/roomoccupancy/policy_test.go +++ b/internal/core/services/autoscaler/policies/roomoccupancy/policy_test.go @@ -195,7 +195,7 @@ func TestCalculateDesiredNumberOfRooms(t *testing.T) { } _, err := policy.CalculateDesiredNumberOfRooms(policyParams, schedulerState) - assert.EqualError(t, err, "Ready target must be between 0 and 1") + assert.EqualError(t, err, "ready target must be greater than 0 and less than 1") }) t.Run("when ready target is greater than 1", func(t *testing.T) { readyTarget := float64(1.1) @@ -212,7 +212,7 @@ func TestCalculateDesiredNumberOfRooms(t *testing.T) { } _, err := policy.CalculateDesiredNumberOfRooms(policyParams, schedulerState) - assert.EqualError(t, err, "Ready target must be between 0 and 1") + assert.EqualError(t, err, "ready target must be greater than 0 and less than 1") }) t.Run("when ready target is 0", func(t *testing.T) { readyTarget := float64(0.0) @@ -229,7 +229,7 @@ func TestCalculateDesiredNumberOfRooms(t *testing.T) { } _, err := policy.CalculateDesiredNumberOfRooms(policyParams, schedulerState) - assert.EqualError(t, err, "Ready target must be between 0 and 1") + assert.EqualError(t, err, "ready target must be greater than 0 and less than 1") }) t.Run("when ready target is lower than 0", func(t *testing.T) { readyTarget := float64(-0.1) @@ -246,7 +246,7 @@ func TestCalculateDesiredNumberOfRooms(t *testing.T) { } _, err := policy.CalculateDesiredNumberOfRooms(policyParams, schedulerState) - assert.EqualError(t, err, "Ready target must be between 0 and 1") + assert.EqualError(t, err, "ready target must be greater than 0 and less than 1") }) }) } @@ -380,7 +380,7 @@ func TestCanDownscale(t *testing.T) { } _, err := policy.CanDownscale(policyParams, schedulerState) - assert.EqualError(t, err, "Downscale threshold must be between 0 and 1") + assert.EqualError(t, err, "downscale threshold must be greater than 0 and less than 1") }) t.Run("when ready target is greater than 1", func(t *testing.T) { downThreshold := float64(1.1) @@ -399,7 +399,7 @@ func TestCanDownscale(t *testing.T) { } _, err := policy.CanDownscale(policyParams, schedulerState) - assert.EqualError(t, err, "Downscale threshold must be between 0 and 1") + assert.EqualError(t, err, "downscale threshold must be greater than 0 and less than 1") }) t.Run("when down threshold is 0", func(t *testing.T) { downThreshold := float64(0.0) @@ -418,7 +418,7 @@ func TestCanDownscale(t *testing.T) { } _, err := policy.CanDownscale(policyParams, schedulerState) - assert.EqualError(t, err, "Downscale threshold must be between 0 and 1") + assert.EqualError(t, err, "downscale threshold must be greater than 0 and less than 1") }) t.Run("when down threshold is lower than 0", func(t *testing.T) { downThreshold := float64(-0.1) @@ -437,7 +437,7 @@ func TestCanDownscale(t *testing.T) { } _, err := policy.CanDownscale(policyParams, schedulerState) - assert.EqualError(t, err, "Downscale threshold must be between 0 and 1") + assert.EqualError(t, err, "downscale threshold must be greater than 0 and less than 1") }) }) } diff --git a/internal/core/services/schedulers/patch/patch_scheduler_test.go b/internal/core/services/schedulers/patch/patch_scheduler_test.go index 3529fc0c6..93cdb6ec7 100644 --- a/internal/core/services/schedulers/patch/patch_scheduler_test.go +++ b/internal/core/services/schedulers/patch/patch_scheduler_test.go @@ -702,7 +702,8 @@ func TestPatchScheduler(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, @@ -720,7 +721,8 @@ func TestPatchScheduler(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, @@ -752,7 +754,8 @@ func TestPatchScheduler(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, @@ -784,7 +787,8 @@ func TestPatchScheduler(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, @@ -812,7 +816,8 @@ func TestPatchScheduler(t *testing.T) { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, @@ -990,7 +995,8 @@ func basicSchedulerToPatchSchedulerTests() *entities.Scheduler { Type: autoscaling.RoomOccupancy, Parameters: autoscaling.PolicyParameters{ RoomOccupancy: &autoscaling.RoomOccupancyParams{ - ReadyTarget: float64(genericFloat32), + ReadyTarget: float64(genericFloat32), + DownThreshold: float64(genericFloat32), }, }, }, diff --git a/pkg/api/v1/messages.pb.go b/pkg/api/v1/messages.pb.go index f5ca25e57..ca653f82f 100644 --- a/pkg/api/v1/messages.pb.go +++ b/pkg/api/v1/messages.pb.go @@ -1596,7 +1596,7 @@ type RoomOccupancy struct { // ReadyTarget represents the number of rooms ready rate that the scheduler should keep ReadyTarget float32 `protobuf:"fixed32,1,opt,name=ready_target,json=readyTarget,proto3" json:"ready_target,omitempty"` // DownThreshold represents the minimum occupation rate that should trigger a scale down - DownThreshold float32 `protobuf:"fixed32,2,opt,name=down_threshold,json=downThreshold,proto3" json:"down_threshold,omitempty"` + DownThreshold *float32 `protobuf:"fixed32,2,opt,name=down_threshold,json=downThreshold,proto3,oneof" json:"down_threshold,omitempty"` } func (x *RoomOccupancy) Reset() { @@ -1639,8 +1639,8 @@ func (x *RoomOccupancy) GetReadyTarget() float32 { } func (x *RoomOccupancy) GetDownThreshold() float32 { - if x != nil { - return x.DownThreshold + if x != nil && x.DownThreshold != nil { + return *x.DownThreshold } return 0 } @@ -2441,82 +2441,84 @@ var file_api_v1_messages_proto_rawDesc = []byte{ 0x52, 0x6f, 0x6f, 0x6d, 0x4f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x4f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x6f, 0x63, 0x63, 0x75, 0x70, - 0x61, 0x6e, 0x63, 0x79, 0x22, 0x59, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x4f, 0x63, 0x63, 0x75, + 0x61, 0x6e, 0x63, 0x79, 0x22, 0x71, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x4f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x72, 0x65, 0x61, - 0x64, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x77, 0x6e, + 0x64, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x0e, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, - 0x52, 0x0d, 0x64, 0x6f, 0x77, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, - 0x19, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x22, 0x61, 0x0a, 0x0e, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x84, 0x01, - 0x0a, 0x10, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, - 0x69, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x22, 0xaa, 0x01, 0x0a, 0x09, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x07, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0x61, 0x0a, 0x10, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, - 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x22, 0x6b, 0x0a, 0x0f, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, - 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, - 0x6e, 0x22, 0xc9, 0x02, 0x0a, 0x0d, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x73, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x6f, 0x6d, - 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, - 0x6f, 0x6f, 0x6d, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x6f, 0x6f, - 0x6d, 0x73, 0x5f, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x69, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x4f, 0x63, 0x63, 0x75, 0x70, 0x69, 0x65, 0x64, - 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x5f, 0x74, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x10, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6e, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, - 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x42, 0x87, 0x01, - 0x92, 0x41, 0x33, 0x12, 0x09, 0x0a, 0x07, 0x4d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2a, 0x02, - 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x6f, 0x70, 0x66, - 0x72, 0x65, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, - 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x5a, 0x2a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x6f, 0x70, 0x66, 0x72, 0x65, 0x65, 0x67, - 0x61, 0x6d, 0x65, 0x73, 0x2f, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x48, 0x00, 0x52, 0x0d, 0x64, 0x6f, 0x77, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x74, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0x19, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x73, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, + 0x74, 0x6c, 0x22, 0x61, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x84, 0x01, 0x0a, 0x10, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xaa, 0x01, 0x0a, + 0x09, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, + 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, + 0x00, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, + 0x08, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x10, 0x46, 0x6f, 0x72, + 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x6b, 0x0a, 0x0f, + 0x41, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, + 0x61, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x1a, 0x0a, + 0x08, 0x63, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x08, 0x63, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0xc9, 0x02, 0x0a, 0x0d, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x6f, 0x6f, + 0x6d, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x52, 0x65, 0x61, 0x64, + 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x5f, 0x6f, 0x63, 0x63, 0x75, 0x70, + 0x69, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x73, + 0x4f, 0x63, 0x63, 0x75, 0x70, 0x69, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, + 0x73, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0c, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, + 0x11, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x5f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x75, + 0x74, 0x6f, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x63, 0x61, + 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x63, + 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x42, 0x87, 0x01, 0x92, 0x41, 0x33, 0x12, 0x09, 0x0a, 0x07, 0x4d, + 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x0a, 0x23, + 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x6f, 0x70, 0x66, 0x72, 0x65, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x73, + 0x2e, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x74, 0x6f, 0x70, 0x66, 0x72, 0x65, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x2f, 0x6d, 0x61, 0x65, + 0x73, 0x74, 0x72, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2953,6 +2955,7 @@ func file_api_v1_messages_proto_init() { file_api_v1_messages_proto_msgTypes[14].OneofWrappers = []interface{}{} file_api_v1_messages_proto_msgTypes[15].OneofWrappers = []interface{}{} file_api_v1_messages_proto_msgTypes[18].OneofWrappers = []interface{}{} + file_api_v1_messages_proto_msgTypes[19].OneofWrappers = []interface{}{} file_api_v1_messages_proto_msgTypes[23].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ diff --git a/proto/api/v1/messages.proto b/proto/api/v1/messages.proto index 8229b8aea..c280aee3b 100644 --- a/proto/api/v1/messages.proto +++ b/proto/api/v1/messages.proto @@ -290,7 +290,7 @@ message RoomOccupancy { // ReadyTarget represents the number of rooms ready rate that the scheduler should keep float ready_target = 1; // DownThreshold represents the minimum occupation rate that should trigger a scale down - float down_threshold = 2; + optional float down_threshold = 2; } // The operation lease object representation