From 765f6a0c13537733f68303f3f9576564c4e5b536 Mon Sep 17 00:00:00 2001 From: vsoch Date: Mon, 3 Jun 2024 16:49:59 -0600 Subject: [PATCH] feat: add metrics and timing functions Problem: we need to record timing of things Solution: this adds a metrics table to the database, which is accessible directly by the same rainbow server that holds the database, and otherwise (for clients that are not directly connected) it can be sent metrics to save. Saving means a name, value, and arbitrary set of key value pairs (both strings). I am also including a pythons script that shows how to read the rainbow database and output the tables. Signed-off-by: vsoch --- api/v1/rainbow.proto | 18 + docs/examples/scheduler/rainbow-config.yaml | 2 +- go.mod | 2 +- pkg/api/v1/rainbow.pb.go | 817 ++++++++++++------- pkg/api/v1/rainbow_grpc.pb.go | 38 + pkg/client/endpoint.go | 54 +- pkg/database/database.go | 13 +- pkg/database/metrics.go | 68 ++ pkg/server/endpoint.go | 36 +- python/v1/README.md | 37 +- python/v1/examples/db/read.py | 61 ++ python/v1/rainbow/client.py | 55 +- python/v1/rainbow/metrics.py | 42 + python/v1/rainbow/protos/rainbow_pb2.py | 84 +- python/v1/rainbow/protos/rainbow_pb2.pyi | 35 +- python/v1/rainbow/protos/rainbow_pb2_grpc.py | 45 + 16 files changed, 1045 insertions(+), 362 deletions(-) create mode 100644 pkg/database/metrics.go create mode 100644 python/v1/examples/db/read.py create mode 100644 python/v1/rainbow/metrics.py diff --git a/api/v1/rainbow.proto b/api/v1/rainbow.proto index 87d7009..208ac4a 100644 --- a/api/v1/rainbow.proto +++ b/api/v1/rainbow.proto @@ -9,6 +9,9 @@ option go_package = "github.com/converged-computing/rainbow/pkg/api/v1"; // RainbowSchedulerService provides API endpoints for interacting with the central scheduler service service RainbowScheduler { + // SaveMetric saves a metric to the database + rpc SaveMetric(SaveMetricRequest) returns (SaveMetricResponse); + // Register cluster - request to register a new cluster rpc Register(RegisterRequest) returns (RegisterResponse); @@ -41,6 +44,20 @@ message RegisterRequest { google.protobuf.Timestamp sent = 5; } +message SaveMetricRequest { + string name = 1; + string value = 2; + map metadata = 3; +} + +message SaveMetricResponse { + enum ResultType { + SAVE_METRIC_SUCCESS = 0; + SAVE_METRIC_ERROR = 1; + } + ResultType status = 1; +} + // UpdateStateRequests allows a cluster to set arbitrary metadata // for its state. State metadata is used for selection algorithms message UpdateStateRequest { @@ -75,6 +92,7 @@ message SubmitJobRequest { map select_options = 5; bool satisfy_only = 6; google.protobuf.Timestamp sent = 7; + int64 jobid = 8; message Cluster { string name = 1; diff --git a/docs/examples/scheduler/rainbow-config.yaml b/docs/examples/scheduler/rainbow-config.yaml index ada6254..47b3a6c 100644 --- a/docs/examples/scheduler/rainbow-config.yaml +++ b/docs/examples/scheduler/rainbow-config.yaml @@ -8,7 +8,7 @@ scheduler: name: match cluster: name: keebler - secret: 27933478-5c96-4473-bd47-b829b5d0eaf9 + secret: e5ef5cfa-662b-453b-bf43-61836a9c5c5d graphdatabase: name: memory host: 127.0.0.1:50051 diff --git a/go.mod b/go.mod index d6127f3..8f5d773 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/compspec/jobspec-go v0.0.0-20240510054255-ee02cdc7d3d4 github.com/converged-computing/jsongraph-go v0.0.0-20240229082022-c6887a5a00fe github.com/fatih/color v1.16.0 + github.com/golang/protobuf v1.5.3 github.com/google/uuid v1.6.0 github.com/mattn/go-sqlite3 v1.14.22 github.com/neo4j/neo4j-go-driver/v5 v5.20.0 @@ -19,7 +20,6 @@ require ( ) require ( - github.com/golang/protobuf v1.5.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect diff --git a/pkg/api/v1/rainbow.pb.go b/pkg/api/v1/rainbow.pb.go index a9de960..ea17fa1 100644 --- a/pkg/api/v1/rainbow.pb.go +++ b/pkg/api/v1/rainbow.pb.go @@ -21,6 +21,52 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type SaveMetricResponse_ResultType int32 + +const ( + SaveMetricResponse_SAVE_METRIC_SUCCESS SaveMetricResponse_ResultType = 0 + SaveMetricResponse_SAVE_METRIC_ERROR SaveMetricResponse_ResultType = 1 +) + +// Enum value maps for SaveMetricResponse_ResultType. +var ( + SaveMetricResponse_ResultType_name = map[int32]string{ + 0: "SAVE_METRIC_SUCCESS", + 1: "SAVE_METRIC_ERROR", + } + SaveMetricResponse_ResultType_value = map[string]int32{ + "SAVE_METRIC_SUCCESS": 0, + "SAVE_METRIC_ERROR": 1, + } +) + +func (x SaveMetricResponse_ResultType) Enum() *SaveMetricResponse_ResultType { + p := new(SaveMetricResponse_ResultType) + *p = x + return p +} + +func (x SaveMetricResponse_ResultType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SaveMetricResponse_ResultType) Descriptor() protoreflect.EnumDescriptor { + return file_rainbow_proto_enumTypes[0].Descriptor() +} + +func (SaveMetricResponse_ResultType) Type() protoreflect.EnumType { + return &file_rainbow_proto_enumTypes[0] +} + +func (x SaveMetricResponse_ResultType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SaveMetricResponse_ResultType.Descriptor instead. +func (SaveMetricResponse_ResultType) EnumDescriptor() ([]byte, []int) { + return file_rainbow_proto_rawDescGZIP(), []int{2, 0} +} + type UpdateStateResponse_ResultType int32 const ( @@ -57,11 +103,11 @@ func (x UpdateStateResponse_ResultType) String() string { } func (UpdateStateResponse_ResultType) Descriptor() protoreflect.EnumDescriptor { - return file_rainbow_proto_enumTypes[0].Descriptor() + return file_rainbow_proto_enumTypes[1].Descriptor() } func (UpdateStateResponse_ResultType) Type() protoreflect.EnumType { - return &file_rainbow_proto_enumTypes[0] + return &file_rainbow_proto_enumTypes[1] } func (x UpdateStateResponse_ResultType) Number() protoreflect.EnumNumber { @@ -70,7 +116,7 @@ func (x UpdateStateResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use UpdateStateResponse_ResultType.Descriptor instead. func (UpdateStateResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{2, 0} + return file_rainbow_proto_rawDescGZIP(), []int{4, 0} } // Registration statuses @@ -113,11 +159,11 @@ func (x RegisterResponse_ResultType) String() string { } func (RegisterResponse_ResultType) Descriptor() protoreflect.EnumDescriptor { - return file_rainbow_proto_enumTypes[1].Descriptor() + return file_rainbow_proto_enumTypes[2].Descriptor() } func (RegisterResponse_ResultType) Type() protoreflect.EnumType { - return &file_rainbow_proto_enumTypes[1] + return &file_rainbow_proto_enumTypes[2] } func (x RegisterResponse_ResultType) Number() protoreflect.EnumNumber { @@ -126,7 +172,7 @@ func (x RegisterResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use RegisterResponse_ResultType.Descriptor instead. func (RegisterResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{6, 0} + return file_rainbow_proto_rawDescGZIP(), []int{8, 0} } // Enum to represent the result types of the operation. @@ -166,11 +212,11 @@ func (x SubmitJobResponse_ResultType) String() string { } func (SubmitJobResponse_ResultType) Descriptor() protoreflect.EnumDescriptor { - return file_rainbow_proto_enumTypes[2].Descriptor() + return file_rainbow_proto_enumTypes[3].Descriptor() } func (SubmitJobResponse_ResultType) Type() protoreflect.EnumType { - return &file_rainbow_proto_enumTypes[2] + return &file_rainbow_proto_enumTypes[3] } func (x SubmitJobResponse_ResultType) Number() protoreflect.EnumNumber { @@ -179,7 +225,7 @@ func (x SubmitJobResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use SubmitJobResponse_ResultType.Descriptor instead. func (SubmitJobResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{7, 0} + return file_rainbow_proto_rawDescGZIP(), []int{9, 0} } // Enum to represent the result types of the operation. @@ -219,11 +265,11 @@ func (x ReceiveJobsResponse_ResultType) String() string { } func (ReceiveJobsResponse_ResultType) Descriptor() protoreflect.EnumDescriptor { - return file_rainbow_proto_enumTypes[3].Descriptor() + return file_rainbow_proto_enumTypes[4].Descriptor() } func (ReceiveJobsResponse_ResultType) Type() protoreflect.EnumType { - return &file_rainbow_proto_enumTypes[3] + return &file_rainbow_proto_enumTypes[4] } func (x ReceiveJobsResponse_ResultType) Number() protoreflect.EnumNumber { @@ -232,7 +278,7 @@ func (x ReceiveJobsResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use ReceiveJobsResponse_ResultType.Descriptor instead. func (ReceiveJobsResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{8, 0} + return file_rainbow_proto_rawDescGZIP(), []int{10, 0} } type AcceptJobsResponse_ResultType int32 @@ -271,11 +317,11 @@ func (x AcceptJobsResponse_ResultType) String() string { } func (AcceptJobsResponse_ResultType) Descriptor() protoreflect.EnumDescriptor { - return file_rainbow_proto_enumTypes[4].Descriptor() + return file_rainbow_proto_enumTypes[5].Descriptor() } func (AcceptJobsResponse_ResultType) Type() protoreflect.EnumType { - return &file_rainbow_proto_enumTypes[4] + return &file_rainbow_proto_enumTypes[5] } func (x AcceptJobsResponse_ResultType) Number() protoreflect.EnumNumber { @@ -284,7 +330,7 @@ func (x AcceptJobsResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use AcceptJobsResponse_ResultType.Descriptor instead. func (AcceptJobsResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{9, 0} + return file_rainbow_proto_rawDescGZIP(), []int{11, 0} } // RegisterRequest registers a cluster to the scheduler service @@ -369,6 +415,116 @@ func (x *RegisterRequest) GetSent() *timestamppb.Timestamp { return nil } +type SaveMetricRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SaveMetricRequest) Reset() { + *x = SaveMetricRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rainbow_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SaveMetricRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SaveMetricRequest) ProtoMessage() {} + +func (x *SaveMetricRequest) ProtoReflect() protoreflect.Message { + mi := &file_rainbow_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SaveMetricRequest.ProtoReflect.Descriptor instead. +func (*SaveMetricRequest) Descriptor() ([]byte, []int) { + return file_rainbow_proto_rawDescGZIP(), []int{1} +} + +func (x *SaveMetricRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SaveMetricRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *SaveMetricRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +type SaveMetricResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status SaveMetricResponse_ResultType `protobuf:"varint,1,opt,name=status,proto3,enum=convergedcomputing.org.grpc.v1.SaveMetricResponse_ResultType" json:"status,omitempty"` +} + +func (x *SaveMetricResponse) Reset() { + *x = SaveMetricResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rainbow_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SaveMetricResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SaveMetricResponse) ProtoMessage() {} + +func (x *SaveMetricResponse) ProtoReflect() protoreflect.Message { + mi := &file_rainbow_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SaveMetricResponse.ProtoReflect.Descriptor instead. +func (*SaveMetricResponse) Descriptor() ([]byte, []int) { + return file_rainbow_proto_rawDescGZIP(), []int{2} +} + +func (x *SaveMetricResponse) GetStatus() SaveMetricResponse_ResultType { + if x != nil { + return x.Status + } + return SaveMetricResponse_SAVE_METRIC_SUCCESS +} + // UpdateStateRequests allows a cluster to set arbitrary metadata // for its state. State metadata is used for selection algorithms type UpdateStateRequest struct { @@ -387,7 +543,7 @@ type UpdateStateRequest struct { func (x *UpdateStateRequest) Reset() { *x = UpdateStateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[1] + mi := &file_rainbow_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -400,7 +556,7 @@ func (x *UpdateStateRequest) String() string { func (*UpdateStateRequest) ProtoMessage() {} func (x *UpdateStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[1] + mi := &file_rainbow_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -413,7 +569,7 @@ func (x *UpdateStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateStateRequest.ProtoReflect.Descriptor instead. func (*UpdateStateRequest) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{1} + return file_rainbow_proto_rawDescGZIP(), []int{3} } func (x *UpdateStateRequest) GetCluster() string { @@ -448,7 +604,7 @@ type UpdateStateResponse struct { func (x *UpdateStateResponse) Reset() { *x = UpdateStateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[2] + mi := &file_rainbow_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -461,7 +617,7 @@ func (x *UpdateStateResponse) String() string { func (*UpdateStateResponse) ProtoMessage() {} func (x *UpdateStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[2] + mi := &file_rainbow_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -474,7 +630,7 @@ func (x *UpdateStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateStateResponse.ProtoReflect.Descriptor instead. func (*UpdateStateResponse) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{2} + return file_rainbow_proto_rawDescGZIP(), []int{4} } func (x *UpdateStateResponse) GetStatus() UpdateStateResponse_ResultType { @@ -499,12 +655,13 @@ type SubmitJobRequest struct { SelectOptions map[string]string `protobuf:"bytes,5,rep,name=select_options,json=selectOptions,proto3" json:"select_options,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` SatisfyOnly bool `protobuf:"varint,6,opt,name=satisfy_only,json=satisfyOnly,proto3" json:"satisfy_only,omitempty"` Sent *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=sent,proto3" json:"sent,omitempty"` + Jobid int64 `protobuf:"varint,8,opt,name=jobid,proto3" json:"jobid,omitempty"` } func (x *SubmitJobRequest) Reset() { *x = SubmitJobRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[3] + mi := &file_rainbow_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -517,7 +674,7 @@ func (x *SubmitJobRequest) String() string { func (*SubmitJobRequest) ProtoMessage() {} func (x *SubmitJobRequest) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[3] + mi := &file_rainbow_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -530,7 +687,7 @@ func (x *SubmitJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitJobRequest.ProtoReflect.Descriptor instead. func (*SubmitJobRequest) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{3} + return file_rainbow_proto_rawDescGZIP(), []int{5} } func (x *SubmitJobRequest) GetName() string { @@ -582,6 +739,13 @@ func (x *SubmitJobRequest) GetSent() *timestamppb.Timestamp { return nil } +func (x *SubmitJobRequest) GetJobid() int64 { + if x != nil { + return x.Jobid + } + return 0 +} + // RequestJobsRequest is used by a cluster (or other entity that can run jobs) // to get back a maximum of N jobs. This will (and should) eventually // support filters / sorting criteria, but now we just take the top @@ -603,7 +767,7 @@ type ReceiveJobsRequest struct { func (x *ReceiveJobsRequest) Reset() { *x = ReceiveJobsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[4] + mi := &file_rainbow_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -616,7 +780,7 @@ func (x *ReceiveJobsRequest) String() string { func (*ReceiveJobsRequest) ProtoMessage() {} func (x *ReceiveJobsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[4] + mi := &file_rainbow_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -629,7 +793,7 @@ func (x *ReceiveJobsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiveJobsRequest.ProtoReflect.Descriptor instead. func (*ReceiveJobsRequest) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{4} + return file_rainbow_proto_rawDescGZIP(), []int{6} } func (x *ReceiveJobsRequest) GetCluster() string { @@ -675,7 +839,7 @@ type AcceptJobsRequest struct { func (x *AcceptJobsRequest) Reset() { *x = AcceptJobsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[5] + mi := &file_rainbow_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -688,7 +852,7 @@ func (x *AcceptJobsRequest) String() string { func (*AcceptJobsRequest) ProtoMessage() {} func (x *AcceptJobsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[5] + mi := &file_rainbow_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -701,7 +865,7 @@ func (x *AcceptJobsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptJobsRequest.ProtoReflect.Descriptor instead. func (*AcceptJobsRequest) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{5} + return file_rainbow_proto_rawDescGZIP(), []int{7} } func (x *AcceptJobsRequest) GetCluster() string { @@ -750,7 +914,7 @@ type RegisterResponse struct { func (x *RegisterResponse) Reset() { *x = RegisterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[6] + mi := &file_rainbow_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -763,7 +927,7 @@ func (x *RegisterResponse) String() string { func (*RegisterResponse) ProtoMessage() {} func (x *RegisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[6] + mi := &file_rainbow_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -776,7 +940,7 @@ func (x *RegisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead. func (*RegisterResponse) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{6} + return file_rainbow_proto_rawDescGZIP(), []int{8} } func (x *RegisterResponse) GetRequestId() string { @@ -824,7 +988,7 @@ type SubmitJobResponse struct { func (x *SubmitJobResponse) Reset() { *x = SubmitJobResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[7] + mi := &file_rainbow_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -837,7 +1001,7 @@ func (x *SubmitJobResponse) String() string { func (*SubmitJobResponse) ProtoMessage() {} func (x *SubmitJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[7] + mi := &file_rainbow_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -850,7 +1014,7 @@ func (x *SubmitJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitJobResponse.ProtoReflect.Descriptor instead. func (*SubmitJobResponse) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{7} + return file_rainbow_proto_rawDescGZIP(), []int{9} } func (x *SubmitJobResponse) GetRequestId() string { @@ -903,7 +1067,7 @@ type ReceiveJobsResponse struct { func (x *ReceiveJobsResponse) Reset() { *x = ReceiveJobsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[8] + mi := &file_rainbow_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -916,7 +1080,7 @@ func (x *ReceiveJobsResponse) String() string { func (*ReceiveJobsResponse) ProtoMessage() {} func (x *ReceiveJobsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[8] + mi := &file_rainbow_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -929,7 +1093,7 @@ func (x *ReceiveJobsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiveJobsResponse.ProtoReflect.Descriptor instead. func (*ReceiveJobsResponse) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{8} + return file_rainbow_proto_rawDescGZIP(), []int{10} } func (x *ReceiveJobsResponse) GetRequestId() string { @@ -965,7 +1129,7 @@ type AcceptJobsResponse struct { func (x *AcceptJobsResponse) Reset() { *x = AcceptJobsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[9] + mi := &file_rainbow_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -978,7 +1142,7 @@ func (x *AcceptJobsResponse) String() string { func (*AcceptJobsResponse) ProtoMessage() {} func (x *AcceptJobsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[9] + mi := &file_rainbow_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -991,7 +1155,7 @@ func (x *AcceptJobsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptJobsResponse.ProtoReflect.Descriptor instead. func (*AcceptJobsResponse) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{9} + return file_rainbow_proto_rawDescGZIP(), []int{11} } func (x *AcceptJobsResponse) GetStatus() AcceptJobsResponse_ResultType { @@ -1013,7 +1177,7 @@ type SubmitJobRequest_Cluster struct { func (x *SubmitJobRequest_Cluster) Reset() { *x = SubmitJobRequest_Cluster{} if protoimpl.UnsafeEnabled { - mi := &file_rainbow_proto_msgTypes[11] + mi := &file_rainbow_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1026,7 +1190,7 @@ func (x *SubmitJobRequest_Cluster) String() string { func (*SubmitJobRequest_Cluster) ProtoMessage() {} func (x *SubmitJobRequest_Cluster) ProtoReflect() protoreflect.Message { - mi := &file_rainbow_proto_msgTypes[11] + mi := &file_rainbow_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1039,7 +1203,7 @@ func (x *SubmitJobRequest_Cluster) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitJobRequest_Cluster.ProtoReflect.Descriptor instead. func (*SubmitJobRequest_Cluster) Descriptor() ([]byte, []int) { - return file_rainbow_proto_rawDescGZIP(), []int{3, 1} + return file_rainbow_proto_rawDescGZIP(), []int{5, 1} } func (x *SubmitJobRequest_Cluster) GetName() string { @@ -1074,204 +1238,237 @@ var file_rainbow_proto_rawDesc = []byte{ 0x73, 0x74, 0x65, 0x6d, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x05, 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, 0x04, - 0x73, 0x65, 0x6e, 0x74, 0x22, 0x60, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xe5, 0x01, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, - 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x76, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, - 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43, - 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0xf7, - 0x03, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x76, + 0x73, 0x65, 0x6e, 0x74, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x5b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa9, + 0x01, 0x0a, 0x12, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, + 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x0a, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x41, + 0x56, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, + 0x53, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x41, 0x56, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x52, + 0x49, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x22, 0x60, 0x0a, 0x12, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xe5, 0x01, 0x0a, + 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, + 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x76, 0x0a, 0x0a, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x10, 0x03, 0x22, 0x8d, 0x04, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, + 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x54, 0x0a, + 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6a, 0x6f, 0x62, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6a, 0x6f, 0x62, 0x73, 0x70, 0x65, 0x63, 0x12, 0x29, 0x0a, + 0x10, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, + 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x6a, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x43, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x79, 0x5f, + 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x61, 0x74, 0x69, + 0x73, 0x66, 0x79, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, + 0x07, 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, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x1a, 0x40, 0x0a, + 0x12, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, + 0x33, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x90, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x61, 0x78, 0x4a, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x6d, 0x61, 0x78, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, + 0x07, 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, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x11, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x05, 0x52, + 0x06, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, + 0x04, 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, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0xb0, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x53, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, - 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, - 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x6a, 0x6f, 0x62, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6a, 0x6f, 0x62, 0x73, 0x70, 0x65, 0x63, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x12, 0x6a, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, - 0x0a, 0x0c, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x79, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x79, 0x4f, 0x6e, 0x6c, - 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x07, 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, 0x04, 0x73, 0x65, 0x6e, - 0x74, 0x1a, 0x40, 0x0a, 0x12, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x33, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x90, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x4a, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x73, - 0x65, 0x6e, 0x74, 0x18, 0x07, 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, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x11, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x05, 0x52, 0x06, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x73, - 0x65, 0x6e, 0x74, 0x18, 0x04, 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, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0xb0, 0x02, 0x0a, 0x10, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x7a, + 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, + 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, + 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, + 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, + 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x4e, + 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, + 0x52, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x04, 0x22, 0xb3, 0x02, 0x0a, 0x11, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x53, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, - 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x22, 0x7a, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, - 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, - 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, - 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, - 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x04, 0x22, 0xb3, - 0x02, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x22, 0x5d, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, - 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, - 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, - 0x45, 0x44, 0x10, 0x03, 0x22, 0x8d, 0x03, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, - 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x04, 0x6a, - 0x6f, 0x62, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, - 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, - 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4a, - 0x6f, 0x62, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x12, 0x56, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, - 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x73, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, - 0x16, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, 0x4e, 0x4f, - 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x53, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x51, - 0x55, 0x45, 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, - 0x53, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x4a, - 0x4f, 0x42, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x52, - 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, 0x44, 0x45, 0x4e, 0x49, - 0x45, 0x44, 0x10, 0x03, 0x22, 0xdf, 0x01, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, - 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x14, 0x0a, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, + 0x54, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x73, 0x22, 0x5d, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x16, 0x0a, 0x12, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x55, 0x42, 0x4d, 0x49, + 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, + 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, + 0x22, 0x8d, 0x03, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, + 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, + 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x12, 0x56, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x22, 0x72, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, - 0x13, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, - 0x54, 0x49, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, - 0x15, 0x0a, 0x11, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x32, 0xd0, 0x05, 0x0a, 0x10, 0x52, 0x61, 0x69, 0x6e, 0x62, - 0x6f, 0x77, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x12, 0x6d, 0x0a, 0x08, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x75, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x73, 0x0a, 0x0a, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x45, 0x51, + 0x55, 0x45, 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, 0x4e, 0x4f, 0x52, 0x45, 0x53, 0x55, + 0x4c, 0x54, 0x53, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, + 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, + 0x16, 0x0a, 0x12, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x42, 0x53, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, + 0x22, 0xdf, 0x01, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, + 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x72, + 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, + 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, + 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, + 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x52, + 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x10, 0x03, 0x32, 0xc5, 0x06, 0x0a, 0x10, 0x52, 0x61, 0x69, 0x6e, 0x62, 0x6f, 0x77, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x12, 0x73, 0x0a, 0x0a, 0x53, 0x61, 0x76, 0x65, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, + 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, + 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x08, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x11, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, - 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, + 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x11, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x70, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x12, - 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, + 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x0b, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x32, 0x2e, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, - 0x62, 0x73, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, + 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, - 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, 0x62, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, - 0x64, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x61, 0x69, 0x6e, - 0x62, 0x6f, 0x77, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, + 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, + 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, + 0x0b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x32, 0x2e, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, + 0x6f, 0x62, 0x73, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, + 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4a, 0x6f, + 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x61, 0x69, + 0x6e, 0x62, 0x6f, 0x77, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1286,59 +1483,67 @@ func file_rainbow_proto_rawDescGZIP() []byte { return file_rainbow_proto_rawDescData } -var file_rainbow_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_rainbow_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_rainbow_proto_enumTypes = make([]protoimpl.EnumInfo, 6) +var file_rainbow_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_rainbow_proto_goTypes = []interface{}{ - (UpdateStateResponse_ResultType)(0), // 0: convergedcomputing.org.grpc.v1.UpdateStateResponse.ResultType - (RegisterResponse_ResultType)(0), // 1: convergedcomputing.org.grpc.v1.RegisterResponse.ResultType - (SubmitJobResponse_ResultType)(0), // 2: convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType - (ReceiveJobsResponse_ResultType)(0), // 3: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.ResultType - (AcceptJobsResponse_ResultType)(0), // 4: convergedcomputing.org.grpc.v1.AcceptJobsResponse.ResultType - (*RegisterRequest)(nil), // 5: convergedcomputing.org.grpc.v1.RegisterRequest - (*UpdateStateRequest)(nil), // 6: convergedcomputing.org.grpc.v1.UpdateStateRequest - (*UpdateStateResponse)(nil), // 7: convergedcomputing.org.grpc.v1.UpdateStateResponse - (*SubmitJobRequest)(nil), // 8: convergedcomputing.org.grpc.v1.SubmitJobRequest - (*ReceiveJobsRequest)(nil), // 9: convergedcomputing.org.grpc.v1.ReceiveJobsRequest - (*AcceptJobsRequest)(nil), // 10: convergedcomputing.org.grpc.v1.AcceptJobsRequest - (*RegisterResponse)(nil), // 11: convergedcomputing.org.grpc.v1.RegisterResponse - (*SubmitJobResponse)(nil), // 12: convergedcomputing.org.grpc.v1.SubmitJobResponse - (*ReceiveJobsResponse)(nil), // 13: convergedcomputing.org.grpc.v1.ReceiveJobsResponse - (*AcceptJobsResponse)(nil), // 14: convergedcomputing.org.grpc.v1.AcceptJobsResponse - nil, // 15: convergedcomputing.org.grpc.v1.SubmitJobRequest.SelectOptionsEntry - (*SubmitJobRequest_Cluster)(nil), // 16: convergedcomputing.org.grpc.v1.SubmitJobRequest.Cluster - nil, // 17: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.JobsEntry - (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp + (SaveMetricResponse_ResultType)(0), // 0: convergedcomputing.org.grpc.v1.SaveMetricResponse.ResultType + (UpdateStateResponse_ResultType)(0), // 1: convergedcomputing.org.grpc.v1.UpdateStateResponse.ResultType + (RegisterResponse_ResultType)(0), // 2: convergedcomputing.org.grpc.v1.RegisterResponse.ResultType + (SubmitJobResponse_ResultType)(0), // 3: convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType + (ReceiveJobsResponse_ResultType)(0), // 4: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.ResultType + (AcceptJobsResponse_ResultType)(0), // 5: convergedcomputing.org.grpc.v1.AcceptJobsResponse.ResultType + (*RegisterRequest)(nil), // 6: convergedcomputing.org.grpc.v1.RegisterRequest + (*SaveMetricRequest)(nil), // 7: convergedcomputing.org.grpc.v1.SaveMetricRequest + (*SaveMetricResponse)(nil), // 8: convergedcomputing.org.grpc.v1.SaveMetricResponse + (*UpdateStateRequest)(nil), // 9: convergedcomputing.org.grpc.v1.UpdateStateRequest + (*UpdateStateResponse)(nil), // 10: convergedcomputing.org.grpc.v1.UpdateStateResponse + (*SubmitJobRequest)(nil), // 11: convergedcomputing.org.grpc.v1.SubmitJobRequest + (*ReceiveJobsRequest)(nil), // 12: convergedcomputing.org.grpc.v1.ReceiveJobsRequest + (*AcceptJobsRequest)(nil), // 13: convergedcomputing.org.grpc.v1.AcceptJobsRequest + (*RegisterResponse)(nil), // 14: convergedcomputing.org.grpc.v1.RegisterResponse + (*SubmitJobResponse)(nil), // 15: convergedcomputing.org.grpc.v1.SubmitJobResponse + (*ReceiveJobsResponse)(nil), // 16: convergedcomputing.org.grpc.v1.ReceiveJobsResponse + (*AcceptJobsResponse)(nil), // 17: convergedcomputing.org.grpc.v1.AcceptJobsResponse + nil, // 18: convergedcomputing.org.grpc.v1.SaveMetricRequest.MetadataEntry + nil, // 19: convergedcomputing.org.grpc.v1.SubmitJobRequest.SelectOptionsEntry + (*SubmitJobRequest_Cluster)(nil), // 20: convergedcomputing.org.grpc.v1.SubmitJobRequest.Cluster + nil, // 21: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.JobsEntry + (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp } var file_rainbow_proto_depIdxs = []int32{ - 18, // 0: convergedcomputing.org.grpc.v1.RegisterRequest.sent:type_name -> google.protobuf.Timestamp - 0, // 1: convergedcomputing.org.grpc.v1.UpdateStateResponse.status:type_name -> convergedcomputing.org.grpc.v1.UpdateStateResponse.ResultType - 16, // 2: convergedcomputing.org.grpc.v1.SubmitJobRequest.clusters:type_name -> convergedcomputing.org.grpc.v1.SubmitJobRequest.Cluster - 15, // 3: convergedcomputing.org.grpc.v1.SubmitJobRequest.select_options:type_name -> convergedcomputing.org.grpc.v1.SubmitJobRequest.SelectOptionsEntry - 18, // 4: convergedcomputing.org.grpc.v1.SubmitJobRequest.sent:type_name -> google.protobuf.Timestamp - 18, // 5: convergedcomputing.org.grpc.v1.ReceiveJobsRequest.sent:type_name -> google.protobuf.Timestamp - 18, // 6: convergedcomputing.org.grpc.v1.AcceptJobsRequest.sent:type_name -> google.protobuf.Timestamp - 1, // 7: convergedcomputing.org.grpc.v1.RegisterResponse.status:type_name -> convergedcomputing.org.grpc.v1.RegisterResponse.ResultType - 2, // 8: convergedcomputing.org.grpc.v1.SubmitJobResponse.status:type_name -> convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType - 17, // 9: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.jobs:type_name -> convergedcomputing.org.grpc.v1.ReceiveJobsResponse.JobsEntry - 3, // 10: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.status:type_name -> convergedcomputing.org.grpc.v1.ReceiveJobsResponse.ResultType - 4, // 11: convergedcomputing.org.grpc.v1.AcceptJobsResponse.status:type_name -> convergedcomputing.org.grpc.v1.AcceptJobsResponse.ResultType - 5, // 12: convergedcomputing.org.grpc.v1.RainbowScheduler.Register:input_type -> convergedcomputing.org.grpc.v1.RegisterRequest - 5, // 13: convergedcomputing.org.grpc.v1.RainbowScheduler.RegisterSubsystem:input_type -> convergedcomputing.org.grpc.v1.RegisterRequest - 8, // 14: convergedcomputing.org.grpc.v1.RainbowScheduler.SubmitJob:input_type -> convergedcomputing.org.grpc.v1.SubmitJobRequest - 6, // 15: convergedcomputing.org.grpc.v1.RainbowScheduler.UpdateState:input_type -> convergedcomputing.org.grpc.v1.UpdateStateRequest - 9, // 16: convergedcomputing.org.grpc.v1.RainbowScheduler.ReceiveJobs:input_type -> convergedcomputing.org.grpc.v1.ReceiveJobsRequest - 10, // 17: convergedcomputing.org.grpc.v1.RainbowScheduler.AcceptJobs:input_type -> convergedcomputing.org.grpc.v1.AcceptJobsRequest - 11, // 18: convergedcomputing.org.grpc.v1.RainbowScheduler.Register:output_type -> convergedcomputing.org.grpc.v1.RegisterResponse - 11, // 19: convergedcomputing.org.grpc.v1.RainbowScheduler.RegisterSubsystem:output_type -> convergedcomputing.org.grpc.v1.RegisterResponse - 12, // 20: convergedcomputing.org.grpc.v1.RainbowScheduler.SubmitJob:output_type -> convergedcomputing.org.grpc.v1.SubmitJobResponse - 7, // 21: convergedcomputing.org.grpc.v1.RainbowScheduler.UpdateState:output_type -> convergedcomputing.org.grpc.v1.UpdateStateResponse - 13, // 22: convergedcomputing.org.grpc.v1.RainbowScheduler.ReceiveJobs:output_type -> convergedcomputing.org.grpc.v1.ReceiveJobsResponse - 14, // 23: convergedcomputing.org.grpc.v1.RainbowScheduler.AcceptJobs:output_type -> convergedcomputing.org.grpc.v1.AcceptJobsResponse - 18, // [18:24] is the sub-list for method output_type - 12, // [12:18] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 22, // 0: convergedcomputing.org.grpc.v1.RegisterRequest.sent:type_name -> google.protobuf.Timestamp + 18, // 1: convergedcomputing.org.grpc.v1.SaveMetricRequest.metadata:type_name -> convergedcomputing.org.grpc.v1.SaveMetricRequest.MetadataEntry + 0, // 2: convergedcomputing.org.grpc.v1.SaveMetricResponse.status:type_name -> convergedcomputing.org.grpc.v1.SaveMetricResponse.ResultType + 1, // 3: convergedcomputing.org.grpc.v1.UpdateStateResponse.status:type_name -> convergedcomputing.org.grpc.v1.UpdateStateResponse.ResultType + 20, // 4: convergedcomputing.org.grpc.v1.SubmitJobRequest.clusters:type_name -> convergedcomputing.org.grpc.v1.SubmitJobRequest.Cluster + 19, // 5: convergedcomputing.org.grpc.v1.SubmitJobRequest.select_options:type_name -> convergedcomputing.org.grpc.v1.SubmitJobRequest.SelectOptionsEntry + 22, // 6: convergedcomputing.org.grpc.v1.SubmitJobRequest.sent:type_name -> google.protobuf.Timestamp + 22, // 7: convergedcomputing.org.grpc.v1.ReceiveJobsRequest.sent:type_name -> google.protobuf.Timestamp + 22, // 8: convergedcomputing.org.grpc.v1.AcceptJobsRequest.sent:type_name -> google.protobuf.Timestamp + 2, // 9: convergedcomputing.org.grpc.v1.RegisterResponse.status:type_name -> convergedcomputing.org.grpc.v1.RegisterResponse.ResultType + 3, // 10: convergedcomputing.org.grpc.v1.SubmitJobResponse.status:type_name -> convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType + 21, // 11: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.jobs:type_name -> convergedcomputing.org.grpc.v1.ReceiveJobsResponse.JobsEntry + 4, // 12: convergedcomputing.org.grpc.v1.ReceiveJobsResponse.status:type_name -> convergedcomputing.org.grpc.v1.ReceiveJobsResponse.ResultType + 5, // 13: convergedcomputing.org.grpc.v1.AcceptJobsResponse.status:type_name -> convergedcomputing.org.grpc.v1.AcceptJobsResponse.ResultType + 7, // 14: convergedcomputing.org.grpc.v1.RainbowScheduler.SaveMetric:input_type -> convergedcomputing.org.grpc.v1.SaveMetricRequest + 6, // 15: convergedcomputing.org.grpc.v1.RainbowScheduler.Register:input_type -> convergedcomputing.org.grpc.v1.RegisterRequest + 6, // 16: convergedcomputing.org.grpc.v1.RainbowScheduler.RegisterSubsystem:input_type -> convergedcomputing.org.grpc.v1.RegisterRequest + 11, // 17: convergedcomputing.org.grpc.v1.RainbowScheduler.SubmitJob:input_type -> convergedcomputing.org.grpc.v1.SubmitJobRequest + 9, // 18: convergedcomputing.org.grpc.v1.RainbowScheduler.UpdateState:input_type -> convergedcomputing.org.grpc.v1.UpdateStateRequest + 12, // 19: convergedcomputing.org.grpc.v1.RainbowScheduler.ReceiveJobs:input_type -> convergedcomputing.org.grpc.v1.ReceiveJobsRequest + 13, // 20: convergedcomputing.org.grpc.v1.RainbowScheduler.AcceptJobs:input_type -> convergedcomputing.org.grpc.v1.AcceptJobsRequest + 8, // 21: convergedcomputing.org.grpc.v1.RainbowScheduler.SaveMetric:output_type -> convergedcomputing.org.grpc.v1.SaveMetricResponse + 14, // 22: convergedcomputing.org.grpc.v1.RainbowScheduler.Register:output_type -> convergedcomputing.org.grpc.v1.RegisterResponse + 14, // 23: convergedcomputing.org.grpc.v1.RainbowScheduler.RegisterSubsystem:output_type -> convergedcomputing.org.grpc.v1.RegisterResponse + 15, // 24: convergedcomputing.org.grpc.v1.RainbowScheduler.SubmitJob:output_type -> convergedcomputing.org.grpc.v1.SubmitJobResponse + 10, // 25: convergedcomputing.org.grpc.v1.RainbowScheduler.UpdateState:output_type -> convergedcomputing.org.grpc.v1.UpdateStateResponse + 16, // 26: convergedcomputing.org.grpc.v1.RainbowScheduler.ReceiveJobs:output_type -> convergedcomputing.org.grpc.v1.ReceiveJobsResponse + 17, // 27: convergedcomputing.org.grpc.v1.RainbowScheduler.AcceptJobs:output_type -> convergedcomputing.org.grpc.v1.AcceptJobsResponse + 21, // [21:28] is the sub-list for method output_type + 14, // [14:21] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_rainbow_proto_init() } @@ -1360,7 +1565,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateStateRequest); i { + switch v := v.(*SaveMetricRequest); i { case 0: return &v.state case 1: @@ -1372,7 +1577,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateStateResponse); i { + switch v := v.(*SaveMetricResponse); i { case 0: return &v.state case 1: @@ -1384,7 +1589,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SubmitJobRequest); i { + switch v := v.(*UpdateStateRequest); i { case 0: return &v.state case 1: @@ -1396,7 +1601,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReceiveJobsRequest); i { + switch v := v.(*UpdateStateResponse); i { case 0: return &v.state case 1: @@ -1408,7 +1613,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AcceptJobsRequest); i { + switch v := v.(*SubmitJobRequest); i { case 0: return &v.state case 1: @@ -1420,7 +1625,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterResponse); i { + switch v := v.(*ReceiveJobsRequest); i { case 0: return &v.state case 1: @@ -1432,7 +1637,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SubmitJobResponse); i { + switch v := v.(*AcceptJobsRequest); i { case 0: return &v.state case 1: @@ -1444,7 +1649,7 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReceiveJobsResponse); i { + switch v := v.(*RegisterResponse); i { case 0: return &v.state case 1: @@ -1456,7 +1661,19 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AcceptJobsResponse); i { + switch v := v.(*SubmitJobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rainbow_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReceiveJobsResponse); i { case 0: return &v.state case 1: @@ -1468,6 +1685,18 @@ func file_rainbow_proto_init() { } } file_rainbow_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AcceptJobsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rainbow_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SubmitJobRequest_Cluster); i { case 0: return &v.state @@ -1485,8 +1714,8 @@ func file_rainbow_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rainbow_proto_rawDesc, - NumEnums: 5, - NumMessages: 13, + NumEnums: 6, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/api/v1/rainbow_grpc.pb.go b/pkg/api/v1/rainbow_grpc.pb.go index 427208a..32dc2c8 100644 --- a/pkg/api/v1/rainbow_grpc.pb.go +++ b/pkg/api/v1/rainbow_grpc.pb.go @@ -22,6 +22,8 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type RainbowSchedulerClient interface { + // SaveMetric saves a metric to the database + SaveMetric(ctx context.Context, in *SaveMetricRequest, opts ...grpc.CallOption) (*SaveMetricResponse, error) // Register cluster - request to register a new cluster Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) // Register cluster - request to register a new cluster @@ -45,6 +47,15 @@ func NewRainbowSchedulerClient(cc grpc.ClientConnInterface) RainbowSchedulerClie return &rainbowSchedulerClient{cc} } +func (c *rainbowSchedulerClient) SaveMetric(ctx context.Context, in *SaveMetricRequest, opts ...grpc.CallOption) (*SaveMetricResponse, error) { + out := new(SaveMetricResponse) + err := c.cc.Invoke(ctx, "/convergedcomputing.org.grpc.v1.RainbowScheduler/SaveMetric", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *rainbowSchedulerClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) { out := new(RegisterResponse) err := c.cc.Invoke(ctx, "/convergedcomputing.org.grpc.v1.RainbowScheduler/Register", in, out, opts...) @@ -103,6 +114,8 @@ func (c *rainbowSchedulerClient) AcceptJobs(ctx context.Context, in *AcceptJobsR // All implementations must embed UnimplementedRainbowSchedulerServer // for forward compatibility type RainbowSchedulerServer interface { + // SaveMetric saves a metric to the database + SaveMetric(context.Context, *SaveMetricRequest) (*SaveMetricResponse, error) // Register cluster - request to register a new cluster Register(context.Context, *RegisterRequest) (*RegisterResponse, error) // Register cluster - request to register a new cluster @@ -123,6 +136,9 @@ type RainbowSchedulerServer interface { type UnimplementedRainbowSchedulerServer struct { } +func (UnimplementedRainbowSchedulerServer) SaveMetric(context.Context, *SaveMetricRequest) (*SaveMetricResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SaveMetric not implemented") +} func (UnimplementedRainbowSchedulerServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Register not implemented") } @@ -154,6 +170,24 @@ func RegisterRainbowSchedulerServer(s grpc.ServiceRegistrar, srv RainbowSchedule s.RegisterService(&RainbowScheduler_ServiceDesc, srv) } +func _RainbowScheduler_SaveMetric_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SaveMetricRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RainbowSchedulerServer).SaveMetric(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/convergedcomputing.org.grpc.v1.RainbowScheduler/SaveMetric", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RainbowSchedulerServer).SaveMetric(ctx, req.(*SaveMetricRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RainbowScheduler_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RegisterRequest) if err := dec(in); err != nil { @@ -269,6 +303,10 @@ var RainbowScheduler_ServiceDesc = grpc.ServiceDesc{ ServiceName: "convergedcomputing.org.grpc.v1.RainbowScheduler", HandlerType: (*RainbowSchedulerServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "SaveMetric", + Handler: _RainbowScheduler_SaveMetric_Handler, + }, { MethodName: "Register", Handler: _RainbowScheduler_Register_Handler, diff --git a/pkg/client/endpoint.go b/pkg/client/endpoint.go index e4aaa31..e3995d6 100644 --- a/pkg/client/endpoint.go +++ b/pkg/client/endpoint.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "time" js "github.com/compspec/jobspec-go/pkg/nextgen/v1" pb "github.com/converged-computing/rainbow/pkg/api/v1" @@ -59,7 +60,28 @@ func (c *RainbowClient) SubmitJob( // (but we limit our search). Likely the first is preferable. // Ask the graphDB if the jobspec can be satisfied // TODO what does a match look like? + + start := time.Now() matches, err := graphDB.Satisfies(job, matchAlgo) + duration := time.Since(start) + + // Here we are checking for the error from Satisfies. We do the save + // call first so we can at least time it + if err != nil { + return response, err + } + + // TIMING: of match algorithm via satisfies + // Prepare the Match time (called via Satisfies) + // Note this is NOT a job id, it is the name from the jobspec to the cluster + in := pb.SaveMetricRequest{ + Name: "satisfies", + Value: duration.String(), + Metadata: map[string]string{"job-name": job.Name}, + } + _, err = c.service.SaveMetric(ctx, &in) + + // Now check for the saving metric error if err != nil { return response, err } @@ -95,6 +117,7 @@ func (c *RainbowClient) SubmitJob( // Validate that the cluster exists, and we have the right token. // The response is the same either way - not found does not reveal // additional information to the client trying to find it + // This function on the server does timing on its own response, err = c.service.SubmitJob(ctx, &pb.SubmitJobRequest{ Name: job.GetJobName(), Clusters: clusters, @@ -212,6 +235,7 @@ func (c *RainbowClient) Register( defer cancel() // Hit the register endpoint + start := time.Now() response, err = c.service.Register(ctx, &pb.RegisterRequest{ Name: cluster, Secret: secret, @@ -219,11 +243,21 @@ func (c *RainbowClient) Register( Subsystem: subsystem, Sent: ts.Now(), }) - - // For now we blindly accept all register, it's a fake endpoint + duration := time.Since(start) if err != nil { return response, errors.Wrap(err, "could not register cluster") } + + // TIMING: of register + in := pb.SaveMetricRequest{ + Name: "register", + Value: duration.String(), + Metadata: map[string]string{"cluster": cluster}, + } + _, err = c.service.SaveMetric(ctx, &in) + if err != nil { + return response, errors.Wrap(err, "could not time 'register' function for cluster") + } return response, nil } @@ -317,6 +351,7 @@ func (c *RainbowClient) RegisterSubsystem( defer cancel() // Hit the register subsystem endpoint + start := time.Now() response, err = c.service.RegisterSubsystem(ctx, &pb.RegisterRequest{ Name: cluster, Secret: secret, @@ -324,12 +359,21 @@ func (c *RainbowClient) RegisterSubsystem( Subsystem: subsystem, Sent: ts.Now(), }) - - // For now we blindly accept all register, it's a fake endpoint - + duration := time.Since(start) if err != nil { return response, errors.Wrap(err, "could not register cluster") } + // TIMING: of register + // Only save if we don't have an error + in := pb.SaveMetricRequest{ + Name: "register-subsystem", + Value: duration.String(), + Metadata: map[string]string{"cluster": cluster, "subsystem": subsystem}, + } + _, err = c.service.SaveMetric(ctx, &in) + if err != nil { + return response, errors.Wrap(err, "could not time 'register-subsystem' function for cluster") + } return response, nil } diff --git a/pkg/database/database.go b/pkg/database/database.go index a353529..8ccc6ff 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -159,6 +159,17 @@ func (db *Database) createTables() error { ); ` + // A metric can be any value (time, memory, etc) important to record + // Some metrics have associated metadata (e.g., jobid) + createMetricTableSQL := ` + CREATE TABLE metrics ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + value TEXT NOT NULL, + metadata TEXT + ); + ` + // A job has a unique id and is assigned a cluster createJobsTableSQL := ` CREATE TABLE jobs ( @@ -170,7 +181,7 @@ func (db *Database) createTables() error { );` // Create single query for tables - createSQL := createClusterTableSQL + "\n" + createJobsTableSQL + createSQL := createClusterTableSQL + "\n" + createJobsTableSQL + "\n" + createMetricTableSQL log.Println(" 🏓️ creating tables...") // Execute SQL query diff --git a/pkg/database/metrics.go b/pkg/database/metrics.go new file mode 100644 index 0000000..74601f1 --- /dev/null +++ b/pkg/database/metrics.go @@ -0,0 +1,68 @@ +package database + +import ( + "encoding/json" + "fmt" + "reflect" + "time" +) + +// WithTime calls a function interface and records a time +// Since we are using it for different scheduling functions, a function name is required. +// We aren't using this because the reflect.Value return needs to be typed! +// This would work nicely for a function that does not need output checked, etc. +func (d *Database) WithTime(fn interface{}, fnName string, params ...interface{}) (result []reflect.Value) { + f := reflect.ValueOf(fn) + if f.Type().NumIn() != len(params) { + panic("incorrect number of parameters!") + } + inputs := make([]reflect.Value, len(params)) + for k, in := range params { + inputs[k] = reflect.ValueOf(in) + } + + start := time.Now() + response := f.Call(inputs) + duration := time.Since(start) + + // Save duration with function name in database, and return response + fmt.Printf("Time for %s took %s", fnName, duration) + d.SaveMetric(fnName, duration.String(), map[string]string{}) + return response +} + +// SaveMetric saves a named metric for a job, optionally with metadata +// the calling function is free to define metadata as they please (format) +func (db *Database) SaveMetric(name, value string, metadata map[string]string) error { + + conn, err := db.connect() + if err != nil { + return err + } + defer conn.Close() + + fmt.Printf("metadata %s\n", metadata) + var fields, values string + if len(metadata) == 0 { + fields = "(name, value)" + values = fmt.Sprintf("(\"%s\", \"%s\")", name, value) + } else { + + // Here we serialize the metadata to bytes + meta, err := json.Marshal(metadata) + if err != nil { + return err + } + fields = "(name, value, metadata)" + values = fmt.Sprintf("(\"%s\", \"%s\", '%s')", name, value, string(meta)) + } + query := fmt.Sprintf("INSERT into metrics %s VALUES %s", fields, values) + fmt.Println(query) + + // Execute SQL query + _, err = conn.Exec(query) + if err != nil { + return err + } + return nil +} diff --git a/pkg/server/endpoint.go b/pkg/server/endpoint.go index 6a329fc..d80171e 100644 --- a/pkg/server/endpoint.go +++ b/pkg/server/endpoint.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "time" pb "github.com/converged-computing/rainbow/pkg/api/v1" "github.com/converged-computing/rainbow/pkg/database" @@ -13,6 +14,31 @@ import ( "github.com/pkg/errors" ) +// SaveMetric saves a metric and associated metadata to the database +func (s *Server) SaveMetric(_ context.Context, in *pb.SaveMetricRequest) (*pb.SaveMetricResponse, error) { + if in == nil { + return nil, errors.New("request is required") + } + + // Assume we start with an error! + response := pb.SaveMetricResponse{Status: pb.SaveMetricResponse_SAVE_METRIC_ERROR} + if in.Name == "" || in.Value == "" { + return &response, errors.New("'Name' and 'Value' are required") + } + metadata := map[string]string{} + if in.Metadata != nil { + for k, v := range in.Metadata { + metadata[k] = v + } + } + err := s.db.SaveMetric(in.Name, in.Value, metadata) + if err != nil { + return &response, err + } + response.Status = pb.SaveMetricResponse_SAVE_METRIC_SUCCESS + return &response, nil +} + // Register a new cluster with the server func (s *Server) Register(_ context.Context, in *pb.RegisterRequest) (*pb.RegisterResponse, error) { if in == nil { @@ -142,8 +168,6 @@ func (s *Server) SubmitJob(_ context.Context, in *pb.SubmitJobRequest) (*pb.Subm } log.Printf("📝️ received job %s for %d contender clusters", in.Name, len(clusters)) - // Get state for clusters. Note that we allow clusters that are missing - // state data - given that the algorithm needs it, they are not included states, err := s.graph.GetStates(clusters) if err != nil { return nil, err @@ -168,8 +192,12 @@ func (s *Server) SubmitJob(_ context.Context, in *pb.SubmitJobRequest) (*pb.Subm } algo = selectAlgo } + // Use the algorithm to select a final cluster, providing states and the jobspec + start := time.Now() selected, err := algo.Select(clusters, states, in.Jobspec, in.SatisfyOnly) + duration := time.Since(start) + s.db.SaveMetric("select", duration.String(), map[string]string{"name": algo.Name()}) if err != nil { return nil, err } @@ -189,7 +217,11 @@ func (s *Server) SubmitJob(_ context.Context, in *pb.SubmitJobRequest) (*pb.Subm } return response, fmt.Errorf("no clusters passed selection") } + + start = time.Now() response, err := s.db.SubmitJob(in, lookup[selected[0]]) + duration = time.Since(start) + s.db.SaveMetric("database-submit-job", duration.String(), map[string]string{}) if err == nil { log.Printf("📝️ job %s is assigned to cluster %s", in.Name, selected) } diff --git a/python/v1/README.md b/python/v1/README.md index 84b2e57..1dce6da 100644 --- a/python/v1/README.md +++ b/python/v1/README.md @@ -40,7 +40,7 @@ The command below will register and save the secret to a new configuration file. Note that if you provide an existing one, it will use or update it. ```bash -python ./examples/flux/register.py keebler --config-path ./rainbow-config.yaml +python ./examples/flux/register.py --cluster blueberry --config-path ./rainbow-config.yaml ``` ```console Saving rainbow config to ./rainbow-config.yaml @@ -72,7 +72,7 @@ and the name `--subsystem` set to "io." This assumes you've registered your clus in your ./rainbow-config.yaml ```bash -python ./examples/flux/register-subsystem.py keebler --config-path ./rainbow-config.yaml +python ./examples/flux/register-subsystem.py --cluster blueberry --config-path ./rainbow-config.yaml ``` ```console status: REGISTER_SUCCESS @@ -105,7 +105,7 @@ In the server window you'll see the subsystem added: While we likely will have clusters sending back state when they accept jobs, for now we have a separate endpoint to do a one-off request to update the state. You can test that here. ```bash -python ./examples/flux/update-state.py keebler --config-path ./rainbow-config.yaml +python ./examples/flux/update-state.py --cluster blueberry --config-path ./rainbow-config.yaml ``` ```console status: UPDATE_STATE_SUCCESS @@ -261,6 +261,37 @@ Received 1 jobs to accept... If this were running in Flux, we would be able to run it, and the response above has told rainbow that you've accepted it (and rainbow deletes the record of it). +### View Metrics + +You can view the tables of the database (and parse them as you please) with the following example: + +```bash +$ python examples/db/read.py +``` +```console +Connecting to database /home/vanessa/Desktop/Code/rainbow/rainbow.db... + + +🥣️ Inspecting clusters table: + name: blueberry, token: rainbow, secret: 362dd73f-7f16-4590-8820-dfa425a29f27 + +📐️ Inspecting metrics table: + id: 1, name: python-client-register, value: 0.013767242431640625, metadata: {"cluster":"blueberry"} + id: 2, name: python-client-register-subsystem, value: 0.0019719600677490234, metadata: {"cluster":"blueberry","subsystem":"io"} + id: 3, name: python-submit-satisfies, value: 0.003846406936645508, metadata: {"jobname":"tart-dog-0410"} + id: 4, name: select, value: 4.122µs, metadata: {"name":"random"} + id: 5, name: database-submit-job, value: 10.645443ms + id: 6, name: python-client-submit-job, value: 0.03459811210632324, metadata: {"jobname":"tart-dog-0410"} + id: 7, name: python-submit-satisfies, value: 0.004126548767089844, metadata: {"jobname":"sticky-dog-7514"} + id: 8, name: select, value: 1.337µs, metadata: {"name":"random"} + id: 9, name: database-submit-job, value: 12.870171ms + id: 10, name: python-client-submit-job, value: 0.03689241409301758, metadata: {"jobname":"sticky-dog-7514"} + +💼️ Inspecting jobs table: + id: 1, cluster: blueberry, name: tart-dog-0410, jobspec: "resources:\n echo:\n replicas: 1\n type: rack\n with:\n - count: 1\n type: node\n with:\n - count: 1\n type: core\ntasks:\n- command:\n - echo\n - hello\n - world\n resources: echo\nversion: 1\n" + id: 2, cluster: blueberry, name: sticky-dog-7514, jobspec: "resources:\n ior:\n replicas: 1\n requires:\n - field: type\n match: shm\n name: io\n type: node\n with:\n - count: 2\n type: core\ntask:\n command:\n - ior\nversion: 1\n" +``` + ## License diff --git a/python/v1/examples/db/read.py b/python/v1/examples/db/read.py new file mode 100644 index 0000000..734a84a --- /dev/null +++ b/python/v1/examples/db/read.py @@ -0,0 +1,61 @@ +import argparse +import os +import sys +import json + +import sqlite3 + +# Config file from a few directories up +here = os.path.abspath(os.path.dirname(__file__)) +root = here + +# rainbow root directory +for iter in range(4): + root = os.path.dirname(root) + + +def get_parser(): + parser = argparse.ArgumentParser(description="🌈️ Rainbow database reader") + parser.add_argument( + "--path", + help="path to sqlite database file", + default=os.path.join(root, "rainbow.db"), + ) + return parser + + +def main(): + parser = get_parser() + args, _ = parser.parse_known_args() + + if not os.path.exists(args.path): + sys.exit(f'{args.path} does not exist') + + print(f'Connecting to database {args.path}...') + conn = sqlite3.connect(args.path) + cursor = conn.cursor() + print(cursor) + + print("\n🥣️ Inspecting clusters table:") + res = cursor.execute("SELECT * FROM clusters") + for cluster in res.fetchall(): + print(f' name: {cluster[0]}, token: {cluster[1]}, secret: {cluster[2]}') + + print("\n📐️ Inspecting metrics table:") + res = cursor.execute("SELECT * FROM metrics") + for metric in res.fetchall(): + result = f' id: {metric[0]}, name: {metric[1]}, value: {metric[2]}' + metadata = metric[3] + if metadata is not None: + result += f', metadata: {metadata}' + print(result) + + print("\n💼️ Inspecting jobs table:") + res = cursor.execute("SELECT * FROM jobs") + for job in res.fetchall(): + print(f' id: {job[0]}, cluster: {job[1]}, name: {job[2]}, jobspec: {json.dumps(job[3])}') + conn.close() + + +if __name__ == "__main__": + main() diff --git a/python/v1/rainbow/client.py b/python/v1/rainbow/client.py index 7dc25b1..70a5e0b 100644 --- a/python/v1/rainbow/client.py +++ b/python/v1/rainbow/client.py @@ -1,5 +1,6 @@ import json import os +import time import grpc import jobspec.core as js @@ -8,6 +9,7 @@ import rainbow.backends as backends import rainbow.config as config import rainbow.defaults as defaults +import rainbow.metrics as metrics import rainbow.types as types import rainbow.utils as utils from rainbow.protos import rainbow_pb2, rainbow_pb2_grpc @@ -96,10 +98,20 @@ def register(self, cluster, secret, cluster_nodes): secret=secret, nodes=nodes, ) + return self.with_time( + "Register", "python-client-register", registerRequest, {"cluster": cluster} + ) - with grpc.insecure_channel(self.host) as channel: - stub = rainbow_pb2_grpc.RainbowSchedulerStub(channel) - response = stub.Register(registerRequest) + def with_time(self, name, funcName, request, metadata): + """ + Make an API call and time it. + + A function (or metric name) is required, along with the + name of the function. Kwargs are optional, and should be metadata. + """ + response, timeResponse = metrics.with_time(name, self.host, funcName, request, metadata) + if timeResponse != 0: + print(f"Warning: issue with saving time: {timeResponse}") return response def update_state(self, cluster, state_data, secret): @@ -126,10 +138,9 @@ def update_state(self, cluster, state_data, secret): secret=secret, payload=json.dumps(payload), ) - with grpc.insecure_channel(self.host) as channel: - stub = rainbow_pb2_grpc.RainbowSchedulerStub(channel) - response = stub.UpdateState(request) - return response + return self.with_time( + "UpdateState", "python-client-update-state", request, {"cluster": cluster} + ) def register_subsystem(self, cluster, subsystem, secret, nodes): """ @@ -152,11 +163,12 @@ def register_subsystem(self, cluster, subsystem, secret, nodes): nodes=nodes, subsystem=subsystem, ) - - with grpc.insecure_channel(self.host) as channel: - stub = rainbow_pb2_grpc.RainbowSchedulerStub(channel) - response = stub.RegisterSubsystem(registerRequest) - return response + return self.with_time( + "RegisterSubsystem", + "python-client-register-subsystem", + registerRequest, + {"subsystem": subsystem, "cluster": cluster}, + ) def load_backend(self): """ @@ -203,7 +215,19 @@ def submit_jobspec( match_algo = match_algo or self.cfg.match_algorithm select_algo = select_algo or self.cfg.selection_algorithm select_options = select_options or self.cfg.selection_algorithm_options + + # Satisfy to the graph endpoint can use a different host than rainbow proper + # This means we time it separately (from here) with the primary rainbow host + start = time.time() satisfy_response = self.backend.satisfies(jobspec, match_algo) + end = time.time() + response = metrics.save_metric( + self.host, "python-submit-satisfies", str(end - start), {"jobname": name} + ) + if response.status != 0: + print("Issue saving metric 'satifies'") + return response + matches = satisfy_response.clusters # No matches? @@ -232,10 +256,9 @@ def submit_jobspec( select_options=select_options, jobspec=jobspec.to_yaml(), ) - - with grpc.insecure_channel(self.host) as channel: - stub = rainbow_pb2_grpc.RainbowSchedulerStub(channel) - response = stub.SubmitJob(submitRequest) + response = self.with_time( + "SubmitJob", "python-client-submit-job", submitRequest, {"jobname": name} + ) res = types.SatisfyResponse( cluster=response.cluster, diff --git a/python/v1/rainbow/metrics.py b/python/v1/rainbow/metrics.py new file mode 100644 index 0000000..1783f2a --- /dev/null +++ b/python/v1/rainbow/metrics.py @@ -0,0 +1,42 @@ +import time + +import grpc + +from rainbow.protos import rainbow_pb2, rainbow_pb2_grpc + + +def with_time(name, host, funcName, request, metadata): + """ + Make an API call and time it. + + A function (or metric name) is required, along with the + name of the function. Kwargs are optional, and should be metadata. + + name: is the name of the API endpoint for the stub + host: hostname for client endpoint + funcName: the "key" of the metric (function being timed) + request: request to go to stub + metadata: arbitrary dict of metadata + """ + with grpc.insecure_channel(host) as channel: + stub = rainbow_pb2_grpc.RainbowSchedulerStub(channel) + func = getattr(stub, name) + start = time.time() + response = func(request) + end = time.time() + saveRequest = rainbow_pb2.SaveMetricRequest( + name=funcName, value=str(end - start), metadata=metadata + ) + saveResponse = stub.SaveMetric(saveRequest) + return response, saveResponse + + +def save_metric(host, name, value, metadata): + """ + Save time to the database + """ + saveRequest = rainbow_pb2.SaveMetricRequest(name=name, value=value, metadata=metadata) + with grpc.insecure_channel(host) as channel: + stub = rainbow_pb2_grpc.RainbowSchedulerStub(channel) + response = stub.SaveMetric(saveRequest) + return response diff --git a/python/v1/rainbow/protos/rainbow_pb2.py b/python/v1/rainbow/protos/rainbow_pb2.py index 7a7cdba..5024f23 100644 --- a/python/v1/rainbow/protos/rainbow_pb2.py +++ b/python/v1/rainbow/protos/rainbow_pb2.py @@ -16,7 +16,7 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\rrainbow.proto\x12\x1e\x63onvergedcomputing.org.grpc.v1\x1a\x1fgoogle/protobuf/timestamp.proto"{\n\x0fRegisterRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\r\n\x05nodes\x18\x03 \x01(\t\x12\x11\n\tsubsystem\x18\x04 \x01(\t\x12(\n\x04sent\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"F\n\x12UpdateStateRequest\x12\x0f\n\x07\x63luster\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\t"\xdd\x01\n\x13UpdateStateResponse\x12N\n\x06status\x18\x01 \x01(\x0e\x32>.convergedcomputing.org.grpc.v1.UpdateStateResponse.ResultType"v\n\nResultType\x12\x1c\n\x18UPDATE_STATE_UNSPECIFIED\x10\x00\x12\x18\n\x14UPDATE_STATE_PARTIAL\x10\x01\x12\x18\n\x14UPDATE_STATE_SUCCESS\x10\x02\x12\x16\n\x12UPDATE_STATE_ERROR\x10\x03"\x92\x03\n\x10SubmitJobRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12J\n\x08\x63lusters\x18\x02 \x03(\x0b\x32\x38.convergedcomputing.org.grpc.v1.SubmitJobRequest.Cluster\x12\x0f\n\x07jobspec\x18\x03 \x01(\t\x12\x18\n\x10select_algorithm\x18\x04 \x01(\t\x12[\n\x0eselect_options\x18\x05 \x03(\x0b\x32\x43.convergedcomputing.org.grpc.v1.SubmitJobRequest.SelectOptionsEntry\x12\x14\n\x0csatisfy_only\x18\x06 \x01(\x08\x12(\n\x04sent\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a\x34\n\x12SelectOptionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a&\n\x07\x43luster\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t"p\n\x12ReceiveJobsRequest\x12\x0f\n\x07\x63luster\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\x0f\n\x07maxJobs\x18\x03 \x01(\x05\x12(\n\x04sent\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"n\n\x11\x41\x63\x63\x65ptJobsRequest\x12\x0f\n\x07\x63luster\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\x0e\n\x06jobids\x18\x03 \x03(\x05\x12(\n\x04sent\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x8e\x02\n\x10RegisterResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x0e\n\x06secret\x18\x03 \x01(\t\x12K\n\x06status\x18\x04 \x01(\x0e\x32;.convergedcomputing.org.grpc.v1.RegisterResponse.ResultType"z\n\nResultType\x12\x18\n\x14REGISTER_UNSPECIFIED\x10\x00\x12\x14\n\x10REGISTER_SUCCESS\x10\x01\x12\x12\n\x0eREGISTER_ERROR\x10\x02\x12\x13\n\x0fREGISTER_DENIED\x10\x03\x12\x13\n\x0fREGISTER_EXISTS\x10\x04"\x86\x02\n\x11SubmitJobResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\r\n\x05jobid\x18\x02 \x01(\x05\x12\x0f\n\x07\x63luster\x18\x03 \x01(\t\x12L\n\x06status\x18\x04 \x01(\x0e\x32<.convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType\x12\x10\n\x08\x63lusters\x18\x05 \x03(\t"]\n\nResultType\x12\x16\n\x12SUBMIT_UNSPECIFIED\x10\x00\x12\x12\n\x0eSUBMIT_SUCCESS\x10\x01\x12\x10\n\x0cSUBMIT_ERROR\x10\x02\x12\x11\n\rSUBMIT_DENIED\x10\x03"\xe8\x02\n\x13ReceiveJobsResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12K\n\x04jobs\x18\x02 \x03(\x0b\x32=.convergedcomputing.org.grpc.v1.ReceiveJobsResponse.JobsEntry\x12N\n\x06status\x18\x03 \x01(\x0e\x32>.convergedcomputing.org.grpc.v1.ReceiveJobsResponse.ResultType\x1a+\n\tJobsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"s\n\nResultType\x12\x1a\n\x16REQUEST_JOBS_NORESULTS\x10\x00\x12\x18\n\x14REQUEST_JOBS_SUCCESS\x10\x01\x12\x16\n\x12REQUEST_JOBS_ERROR\x10\x02\x12\x17\n\x13REQUEST_JOBS_DENIED\x10\x03"\xd7\x01\n\x12\x41\x63\x63\x65ptJobsResponse\x12M\n\x06status\x18\x01 \x01(\x0e\x32=.convergedcomputing.org.grpc.v1.AcceptJobsResponse.ResultType"r\n\nResultType\x12\x1b\n\x17RESULT_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13RESULT_TYPE_PARTIAL\x10\x01\x12\x17\n\x13RESULT_TYPE_SUCCESS\x10\x02\x12\x15\n\x11RESULT_TYPE_ERROR\x10\x03\x32\xd0\x05\n\x10RainbowScheduler\x12m\n\x08Register\x12/.convergedcomputing.org.grpc.v1.RegisterRequest\x1a\x30.convergedcomputing.org.grpc.v1.RegisterResponse\x12v\n\x11RegisterSubsystem\x12/.convergedcomputing.org.grpc.v1.RegisterRequest\x1a\x30.convergedcomputing.org.grpc.v1.RegisterResponse\x12p\n\tSubmitJob\x12\x30.convergedcomputing.org.grpc.v1.SubmitJobRequest\x1a\x31.convergedcomputing.org.grpc.v1.SubmitJobResponse\x12v\n\x0bUpdateState\x12\x32.convergedcomputing.org.grpc.v1.UpdateStateRequest\x1a\x33.convergedcomputing.org.grpc.v1.UpdateStateResponse\x12v\n\x0bReceiveJobs\x12\x32.convergedcomputing.org.grpc.v1.ReceiveJobsRequest\x1a\x33.convergedcomputing.org.grpc.v1.ReceiveJobsResponse\x12s\n\nAcceptJobs\x12\x31.convergedcomputing.org.grpc.v1.AcceptJobsRequest\x1a\x32.convergedcomputing.org.grpc.v1.AcceptJobsResponseB3Z1github.com/converged-computing/rainbow/pkg/api/v1b\x06proto3' + b'\n\rrainbow.proto\x12\x1e\x63onvergedcomputing.org.grpc.v1\x1a\x1fgoogle/protobuf/timestamp.proto"{\n\x0fRegisterRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\r\n\x05nodes\x18\x03 \x01(\t\x12\x11\n\tsubsystem\x18\x04 \x01(\t\x12(\n\x04sent\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xb4\x01\n\x11SaveMetricRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12Q\n\x08metadata\x18\x03 \x03(\x0b\x32?.convergedcomputing.org.grpc.v1.SaveMetricRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\xa1\x01\n\x12SaveMetricResponse\x12M\n\x06status\x18\x01 \x01(\x0e\x32=.convergedcomputing.org.grpc.v1.SaveMetricResponse.ResultType"<\n\nResultType\x12\x17\n\x13SAVE_METRIC_SUCCESS\x10\x00\x12\x15\n\x11SAVE_METRIC_ERROR\x10\x01"F\n\x12UpdateStateRequest\x12\x0f\n\x07\x63luster\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\t"\xdd\x01\n\x13UpdateStateResponse\x12N\n\x06status\x18\x01 \x01(\x0e\x32>.convergedcomputing.org.grpc.v1.UpdateStateResponse.ResultType"v\n\nResultType\x12\x1c\n\x18UPDATE_STATE_UNSPECIFIED\x10\x00\x12\x18\n\x14UPDATE_STATE_PARTIAL\x10\x01\x12\x18\n\x14UPDATE_STATE_SUCCESS\x10\x02\x12\x16\n\x12UPDATE_STATE_ERROR\x10\x03"\xa1\x03\n\x10SubmitJobRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12J\n\x08\x63lusters\x18\x02 \x03(\x0b\x32\x38.convergedcomputing.org.grpc.v1.SubmitJobRequest.Cluster\x12\x0f\n\x07jobspec\x18\x03 \x01(\t\x12\x18\n\x10select_algorithm\x18\x04 \x01(\t\x12[\n\x0eselect_options\x18\x05 \x03(\x0b\x32\x43.convergedcomputing.org.grpc.v1.SubmitJobRequest.SelectOptionsEntry\x12\x14\n\x0csatisfy_only\x18\x06 \x01(\x08\x12(\n\x04sent\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\r\n\x05jobid\x18\x08 \x01(\x03\x1a\x34\n\x12SelectOptionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a&\n\x07\x43luster\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t"p\n\x12ReceiveJobsRequest\x12\x0f\n\x07\x63luster\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\x0f\n\x07maxJobs\x18\x03 \x01(\x05\x12(\n\x04sent\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"n\n\x11\x41\x63\x63\x65ptJobsRequest\x12\x0f\n\x07\x63luster\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\x12\x0e\n\x06jobids\x18\x03 \x03(\x05\x12(\n\x04sent\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x8e\x02\n\x10RegisterResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x0e\n\x06secret\x18\x03 \x01(\t\x12K\n\x06status\x18\x04 \x01(\x0e\x32;.convergedcomputing.org.grpc.v1.RegisterResponse.ResultType"z\n\nResultType\x12\x18\n\x14REGISTER_UNSPECIFIED\x10\x00\x12\x14\n\x10REGISTER_SUCCESS\x10\x01\x12\x12\n\x0eREGISTER_ERROR\x10\x02\x12\x13\n\x0fREGISTER_DENIED\x10\x03\x12\x13\n\x0fREGISTER_EXISTS\x10\x04"\x86\x02\n\x11SubmitJobResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\r\n\x05jobid\x18\x02 \x01(\x05\x12\x0f\n\x07\x63luster\x18\x03 \x01(\t\x12L\n\x06status\x18\x04 \x01(\x0e\x32<.convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType\x12\x10\n\x08\x63lusters\x18\x05 \x03(\t"]\n\nResultType\x12\x16\n\x12SUBMIT_UNSPECIFIED\x10\x00\x12\x12\n\x0eSUBMIT_SUCCESS\x10\x01\x12\x10\n\x0cSUBMIT_ERROR\x10\x02\x12\x11\n\rSUBMIT_DENIED\x10\x03"\xe8\x02\n\x13ReceiveJobsResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12K\n\x04jobs\x18\x02 \x03(\x0b\x32=.convergedcomputing.org.grpc.v1.ReceiveJobsResponse.JobsEntry\x12N\n\x06status\x18\x03 \x01(\x0e\x32>.convergedcomputing.org.grpc.v1.ReceiveJobsResponse.ResultType\x1a+\n\tJobsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"s\n\nResultType\x12\x1a\n\x16REQUEST_JOBS_NORESULTS\x10\x00\x12\x18\n\x14REQUEST_JOBS_SUCCESS\x10\x01\x12\x16\n\x12REQUEST_JOBS_ERROR\x10\x02\x12\x17\n\x13REQUEST_JOBS_DENIED\x10\x03"\xd7\x01\n\x12\x41\x63\x63\x65ptJobsResponse\x12M\n\x06status\x18\x01 \x01(\x0e\x32=.convergedcomputing.org.grpc.v1.AcceptJobsResponse.ResultType"r\n\nResultType\x12\x1b\n\x17RESULT_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13RESULT_TYPE_PARTIAL\x10\x01\x12\x17\n\x13RESULT_TYPE_SUCCESS\x10\x02\x12\x15\n\x11RESULT_TYPE_ERROR\x10\x03\x32\xc5\x06\n\x10RainbowScheduler\x12s\n\nSaveMetric\x12\x31.convergedcomputing.org.grpc.v1.SaveMetricRequest\x1a\x32.convergedcomputing.org.grpc.v1.SaveMetricResponse\x12m\n\x08Register\x12/.convergedcomputing.org.grpc.v1.RegisterRequest\x1a\x30.convergedcomputing.org.grpc.v1.RegisterResponse\x12v\n\x11RegisterSubsystem\x12/.convergedcomputing.org.grpc.v1.RegisterRequest\x1a\x30.convergedcomputing.org.grpc.v1.RegisterResponse\x12p\n\tSubmitJob\x12\x30.convergedcomputing.org.grpc.v1.SubmitJobRequest\x1a\x31.convergedcomputing.org.grpc.v1.SubmitJobResponse\x12v\n\x0bUpdateState\x12\x32.convergedcomputing.org.grpc.v1.UpdateStateRequest\x1a\x33.convergedcomputing.org.grpc.v1.UpdateStateResponse\x12v\n\x0bReceiveJobs\x12\x32.convergedcomputing.org.grpc.v1.ReceiveJobsRequest\x1a\x33.convergedcomputing.org.grpc.v1.ReceiveJobsResponse\x12s\n\nAcceptJobs\x12\x31.convergedcomputing.org.grpc.v1.AcceptJobsRequest\x1a\x32.convergedcomputing.org.grpc.v1.AcceptJobsResponseB3Z1github.com/converged-computing/rainbow/pkg/api/v1b\x06proto3' ) _globals = globals() @@ -27,46 +27,56 @@ _globals[ "DESCRIPTOR" ]._serialized_options = b"Z1github.com/converged-computing/rainbow/pkg/api/v1" + _globals["_SAVEMETRICREQUEST_METADATAENTRY"]._options = None + _globals["_SAVEMETRICREQUEST_METADATAENTRY"]._serialized_options = b"8\001" _globals["_SUBMITJOBREQUEST_SELECTOPTIONSENTRY"]._options = None _globals["_SUBMITJOBREQUEST_SELECTOPTIONSENTRY"]._serialized_options = b"8\001" _globals["_RECEIVEJOBSRESPONSE_JOBSENTRY"]._options = None _globals["_RECEIVEJOBSRESPONSE_JOBSENTRY"]._serialized_options = b"8\001" _globals["_REGISTERREQUEST"]._serialized_start = 82 _globals["_REGISTERREQUEST"]._serialized_end = 205 - _globals["_UPDATESTATEREQUEST"]._serialized_start = 207 - _globals["_UPDATESTATEREQUEST"]._serialized_end = 277 - _globals["_UPDATESTATERESPONSE"]._serialized_start = 280 - _globals["_UPDATESTATERESPONSE"]._serialized_end = 501 - _globals["_UPDATESTATERESPONSE_RESULTTYPE"]._serialized_start = 383 - _globals["_UPDATESTATERESPONSE_RESULTTYPE"]._serialized_end = 501 - _globals["_SUBMITJOBREQUEST"]._serialized_start = 504 - _globals["_SUBMITJOBREQUEST"]._serialized_end = 906 - _globals["_SUBMITJOBREQUEST_SELECTOPTIONSENTRY"]._serialized_start = 814 - _globals["_SUBMITJOBREQUEST_SELECTOPTIONSENTRY"]._serialized_end = 866 - _globals["_SUBMITJOBREQUEST_CLUSTER"]._serialized_start = 868 - _globals["_SUBMITJOBREQUEST_CLUSTER"]._serialized_end = 906 - _globals["_RECEIVEJOBSREQUEST"]._serialized_start = 908 - _globals["_RECEIVEJOBSREQUEST"]._serialized_end = 1020 - _globals["_ACCEPTJOBSREQUEST"]._serialized_start = 1022 - _globals["_ACCEPTJOBSREQUEST"]._serialized_end = 1132 - _globals["_REGISTERRESPONSE"]._serialized_start = 1135 - _globals["_REGISTERRESPONSE"]._serialized_end = 1405 - _globals["_REGISTERRESPONSE_RESULTTYPE"]._serialized_start = 1283 - _globals["_REGISTERRESPONSE_RESULTTYPE"]._serialized_end = 1405 - _globals["_SUBMITJOBRESPONSE"]._serialized_start = 1408 - _globals["_SUBMITJOBRESPONSE"]._serialized_end = 1670 - _globals["_SUBMITJOBRESPONSE_RESULTTYPE"]._serialized_start = 1577 - _globals["_SUBMITJOBRESPONSE_RESULTTYPE"]._serialized_end = 1670 - _globals["_RECEIVEJOBSRESPONSE"]._serialized_start = 1673 - _globals["_RECEIVEJOBSRESPONSE"]._serialized_end = 2033 - _globals["_RECEIVEJOBSRESPONSE_JOBSENTRY"]._serialized_start = 1873 - _globals["_RECEIVEJOBSRESPONSE_JOBSENTRY"]._serialized_end = 1916 - _globals["_RECEIVEJOBSRESPONSE_RESULTTYPE"]._serialized_start = 1918 - _globals["_RECEIVEJOBSRESPONSE_RESULTTYPE"]._serialized_end = 2033 - _globals["_ACCEPTJOBSRESPONSE"]._serialized_start = 2036 - _globals["_ACCEPTJOBSRESPONSE"]._serialized_end = 2251 - _globals["_ACCEPTJOBSRESPONSE_RESULTTYPE"]._serialized_start = 2137 - _globals["_ACCEPTJOBSRESPONSE_RESULTTYPE"]._serialized_end = 2251 - _globals["_RAINBOWSCHEDULER"]._serialized_start = 2254 - _globals["_RAINBOWSCHEDULER"]._serialized_end = 2974 + _globals["_SAVEMETRICREQUEST"]._serialized_start = 208 + _globals["_SAVEMETRICREQUEST"]._serialized_end = 388 + _globals["_SAVEMETRICREQUEST_METADATAENTRY"]._serialized_start = 341 + _globals["_SAVEMETRICREQUEST_METADATAENTRY"]._serialized_end = 388 + _globals["_SAVEMETRICRESPONSE"]._serialized_start = 391 + _globals["_SAVEMETRICRESPONSE"]._serialized_end = 552 + _globals["_SAVEMETRICRESPONSE_RESULTTYPE"]._serialized_start = 492 + _globals["_SAVEMETRICRESPONSE_RESULTTYPE"]._serialized_end = 552 + _globals["_UPDATESTATEREQUEST"]._serialized_start = 554 + _globals["_UPDATESTATEREQUEST"]._serialized_end = 624 + _globals["_UPDATESTATERESPONSE"]._serialized_start = 627 + _globals["_UPDATESTATERESPONSE"]._serialized_end = 848 + _globals["_UPDATESTATERESPONSE_RESULTTYPE"]._serialized_start = 730 + _globals["_UPDATESTATERESPONSE_RESULTTYPE"]._serialized_end = 848 + _globals["_SUBMITJOBREQUEST"]._serialized_start = 851 + _globals["_SUBMITJOBREQUEST"]._serialized_end = 1268 + _globals["_SUBMITJOBREQUEST_SELECTOPTIONSENTRY"]._serialized_start = 1176 + _globals["_SUBMITJOBREQUEST_SELECTOPTIONSENTRY"]._serialized_end = 1228 + _globals["_SUBMITJOBREQUEST_CLUSTER"]._serialized_start = 1230 + _globals["_SUBMITJOBREQUEST_CLUSTER"]._serialized_end = 1268 + _globals["_RECEIVEJOBSREQUEST"]._serialized_start = 1270 + _globals["_RECEIVEJOBSREQUEST"]._serialized_end = 1382 + _globals["_ACCEPTJOBSREQUEST"]._serialized_start = 1384 + _globals["_ACCEPTJOBSREQUEST"]._serialized_end = 1494 + _globals["_REGISTERRESPONSE"]._serialized_start = 1497 + _globals["_REGISTERRESPONSE"]._serialized_end = 1767 + _globals["_REGISTERRESPONSE_RESULTTYPE"]._serialized_start = 1645 + _globals["_REGISTERRESPONSE_RESULTTYPE"]._serialized_end = 1767 + _globals["_SUBMITJOBRESPONSE"]._serialized_start = 1770 + _globals["_SUBMITJOBRESPONSE"]._serialized_end = 2032 + _globals["_SUBMITJOBRESPONSE_RESULTTYPE"]._serialized_start = 1939 + _globals["_SUBMITJOBRESPONSE_RESULTTYPE"]._serialized_end = 2032 + _globals["_RECEIVEJOBSRESPONSE"]._serialized_start = 2035 + _globals["_RECEIVEJOBSRESPONSE"]._serialized_end = 2395 + _globals["_RECEIVEJOBSRESPONSE_JOBSENTRY"]._serialized_start = 2235 + _globals["_RECEIVEJOBSRESPONSE_JOBSENTRY"]._serialized_end = 2278 + _globals["_RECEIVEJOBSRESPONSE_RESULTTYPE"]._serialized_start = 2280 + _globals["_RECEIVEJOBSRESPONSE_RESULTTYPE"]._serialized_end = 2395 + _globals["_ACCEPTJOBSRESPONSE"]._serialized_start = 2398 + _globals["_ACCEPTJOBSRESPONSE"]._serialized_end = 2613 + _globals["_ACCEPTJOBSRESPONSE_RESULTTYPE"]._serialized_start = 2499 + _globals["_ACCEPTJOBSRESPONSE_RESULTTYPE"]._serialized_end = 2613 + _globals["_RAINBOWSCHEDULER"]._serialized_start = 2616 + _globals["_RAINBOWSCHEDULER"]._serialized_end = 3453 # @@protoc_insertion_point(module_scope) diff --git a/python/v1/rainbow/protos/rainbow_pb2.pyi b/python/v1/rainbow/protos/rainbow_pb2.pyi index cc6f3ef..f0a1152 100644 --- a/python/v1/rainbow/protos/rainbow_pb2.pyi +++ b/python/v1/rainbow/protos/rainbow_pb2.pyi @@ -21,6 +21,35 @@ class RegisterRequest(_message.Message): sent: _timestamp_pb2.Timestamp def __init__(self, name: _Optional[str] = ..., secret: _Optional[str] = ..., nodes: _Optional[str] = ..., subsystem: _Optional[str] = ..., sent: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... +class SaveMetricRequest(_message.Message): + __slots__ = ("name", "value", "metadata") + class MetadataEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + name: str + value: str + metadata: _containers.ScalarMap[str, str] + def __init__(self, name: _Optional[str] = ..., value: _Optional[str] = ..., metadata: _Optional[_Mapping[str, str]] = ...) -> None: ... + +class SaveMetricResponse(_message.Message): + __slots__ = ("status",) + class ResultType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + SAVE_METRIC_SUCCESS: _ClassVar[SaveMetricResponse.ResultType] + SAVE_METRIC_ERROR: _ClassVar[SaveMetricResponse.ResultType] + SAVE_METRIC_SUCCESS: SaveMetricResponse.ResultType + SAVE_METRIC_ERROR: SaveMetricResponse.ResultType + STATUS_FIELD_NUMBER: _ClassVar[int] + status: SaveMetricResponse.ResultType + def __init__(self, status: _Optional[_Union[SaveMetricResponse.ResultType, str]] = ...) -> None: ... + class UpdateStateRequest(_message.Message): __slots__ = ("cluster", "secret", "payload") CLUSTER_FIELD_NUMBER: _ClassVar[int] @@ -48,7 +77,7 @@ class UpdateStateResponse(_message.Message): def __init__(self, status: _Optional[_Union[UpdateStateResponse.ResultType, str]] = ...) -> None: ... class SubmitJobRequest(_message.Message): - __slots__ = ("name", "clusters", "jobspec", "select_algorithm", "select_options", "satisfy_only", "sent") + __slots__ = ("name", "clusters", "jobspec", "select_algorithm", "select_options", "satisfy_only", "sent", "jobid") class SelectOptionsEntry(_message.Message): __slots__ = ("key", "value") KEY_FIELD_NUMBER: _ClassVar[int] @@ -70,6 +99,7 @@ class SubmitJobRequest(_message.Message): SELECT_OPTIONS_FIELD_NUMBER: _ClassVar[int] SATISFY_ONLY_FIELD_NUMBER: _ClassVar[int] SENT_FIELD_NUMBER: _ClassVar[int] + JOBID_FIELD_NUMBER: _ClassVar[int] name: str clusters: _containers.RepeatedCompositeFieldContainer[SubmitJobRequest.Cluster] jobspec: str @@ -77,7 +107,8 @@ class SubmitJobRequest(_message.Message): select_options: _containers.ScalarMap[str, str] satisfy_only: bool sent: _timestamp_pb2.Timestamp - def __init__(self, name: _Optional[str] = ..., clusters: _Optional[_Iterable[_Union[SubmitJobRequest.Cluster, _Mapping]]] = ..., jobspec: _Optional[str] = ..., select_algorithm: _Optional[str] = ..., select_options: _Optional[_Mapping[str, str]] = ..., satisfy_only: bool = ..., sent: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... + jobid: int + def __init__(self, name: _Optional[str] = ..., clusters: _Optional[_Iterable[_Union[SubmitJobRequest.Cluster, _Mapping]]] = ..., jobspec: _Optional[str] = ..., select_algorithm: _Optional[str] = ..., select_options: _Optional[_Mapping[str, str]] = ..., satisfy_only: bool = ..., sent: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., jobid: _Optional[int] = ...) -> None: ... class ReceiveJobsRequest(_message.Message): __slots__ = ("cluster", "secret", "maxJobs", "sent") diff --git a/python/v1/rainbow/protos/rainbow_pb2_grpc.py b/python/v1/rainbow/protos/rainbow_pb2_grpc.py index 2211f2e..a2d4792 100644 --- a/python/v1/rainbow/protos/rainbow_pb2_grpc.py +++ b/python/v1/rainbow/protos/rainbow_pb2_grpc.py @@ -14,6 +14,11 @@ def __init__(self, channel): Args: channel: A grpc.Channel. """ + self.SaveMetric = channel.unary_unary( + "/convergedcomputing.org.grpc.v1.RainbowScheduler/SaveMetric", + request_serializer=rainbow__pb2.SaveMetricRequest.SerializeToString, + response_deserializer=rainbow__pb2.SaveMetricResponse.FromString, + ) self.Register = channel.unary_unary( "/convergedcomputing.org.grpc.v1.RainbowScheduler/Register", request_serializer=rainbow__pb2.RegisterRequest.SerializeToString, @@ -49,6 +54,12 @@ def __init__(self, channel): class RainbowSchedulerServicer(object): """RainbowSchedulerService provides API endpoints for interacting with the central scheduler service""" + def SaveMetric(self, request, context): + """SaveMetric saves a metric to the database""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + def Register(self, request, context): """Register cluster - request to register a new cluster""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -90,6 +101,11 @@ def AcceptJobs(self, request, context): def add_RainbowSchedulerServicer_to_server(servicer, server): rpc_method_handlers = { + "SaveMetric": grpc.unary_unary_rpc_method_handler( + servicer.SaveMetric, + request_deserializer=rainbow__pb2.SaveMetricRequest.FromString, + response_serializer=rainbow__pb2.SaveMetricResponse.SerializeToString, + ), "Register": grpc.unary_unary_rpc_method_handler( servicer.Register, request_deserializer=rainbow__pb2.RegisterRequest.FromString, @@ -131,6 +147,35 @@ def add_RainbowSchedulerServicer_to_server(servicer, server): class RainbowScheduler(object): """RainbowSchedulerService provides API endpoints for interacting with the central scheduler service""" + @staticmethod + def SaveMetric( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/convergedcomputing.org.grpc.v1.RainbowScheduler/SaveMetric", + rainbow__pb2.SaveMetricRequest.SerializeToString, + rainbow__pb2.SaveMetricResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + @staticmethod def Register( request,