diff --git a/cmd/gorse-server/main.go b/cmd/gorse-server/main.go index b87abfda6..7c923ffca 100644 --- a/cmd/gorse-server/main.go +++ b/cmd/gorse-server/main.go @@ -21,7 +21,7 @@ import ( "github.com/spf13/cobra" "github.com/zhenghaoz/gorse/base/log" "github.com/zhenghaoz/gorse/cmd/version" - "github.com/zhenghaoz/gorse/protocol" + "github.com/zhenghaoz/gorse/common/util" "github.com/zhenghaoz/gorse/server" "go.uber.org/zap" ) @@ -50,9 +50,9 @@ var serverCommand = &cobra.Command{ caFile, _ := cmd.PersistentFlags().GetString("ssl-ca") certFile, _ := cmd.PersistentFlags().GetString("ssl-cert") keyFile, _ := cmd.PersistentFlags().GetString("ssl-key") - var tlsConfig *protocol.TLSConfig + var tlsConfig *util.TLSConfig if caFile != "" && certFile != "" && keyFile != "" { - tlsConfig = &protocol.TLSConfig{ + tlsConfig = &util.TLSConfig{ SSLCA: caFile, SSLCert: certFile, SSLKey: keyFile, diff --git a/cmd/gorse-worker/main.go b/cmd/gorse-worker/main.go index 4cf9927ee..fee553828 100644 --- a/cmd/gorse-worker/main.go +++ b/cmd/gorse-worker/main.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" "github.com/zhenghaoz/gorse/base/log" "github.com/zhenghaoz/gorse/cmd/version" - "github.com/zhenghaoz/gorse/protocol" + "github.com/zhenghaoz/gorse/common/util" "github.com/zhenghaoz/gorse/worker" "go.uber.org/zap" ) @@ -49,9 +49,9 @@ var workerCommand = &cobra.Command{ caFile, _ := cmd.PersistentFlags().GetString("ssl-ca") certFile, _ := cmd.PersistentFlags().GetString("ssl-cert") keyFile, _ := cmd.PersistentFlags().GetString("ssl-key") - var tlsConfig *protocol.TLSConfig + var tlsConfig *util.TLSConfig if caFile != "" && certFile != "" && keyFile != "" { - tlsConfig = &protocol.TLSConfig{ + tlsConfig = &util.TLSConfig{ SSLCA: caFile, SSLCert: certFile, SSLKey: keyFile, diff --git a/protocol/decoder.go b/common/encoding/decoder.go similarity index 90% rename from protocol/decoder.go rename to common/encoding/decoder.go index 865e10909..0ff562496 100644 --- a/protocol/decoder.go +++ b/common/encoding/decoder.go @@ -12,18 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package protocol +package encoding import ( "github.com/zhenghaoz/gorse/base/log" "github.com/zhenghaoz/gorse/model/click" "github.com/zhenghaoz/gorse/model/ranking" + "github.com/zhenghaoz/gorse/protocol" "go.uber.org/zap" "io" ) // UnmarshalClickModel unmarshal click model from gRPC. -func UnmarshalClickModel(receiver Master_GetClickModelClient) (click.FactorizationMachine, error) { +func UnmarshalClickModel(receiver protocol.Master_GetClickModelClient) (click.FactorizationMachine, error) { // receive model reader, writer := io.Pipe() var finalError error @@ -66,7 +67,7 @@ func UnmarshalClickModel(receiver Master_GetClickModelClient) (click.Factorizati } // UnmarshalRankingModel unmarshal ranking model from gRPC. -func UnmarshalRankingModel(receiver Master_GetRankingModelClient) (ranking.MatrixFactorization, error) { +func UnmarshalRankingModel(receiver protocol.Master_GetRankingModelClient) (ranking.MatrixFactorization, error) { // receive model reader, writer := io.Pipe() var receiverError error diff --git a/common/nn/layers.go b/common/nn/layers.go index ce93af37c..12999e700 100644 --- a/common/nn/layers.go +++ b/common/nn/layers.go @@ -14,7 +14,16 @@ package nn -import "github.com/chewxy/math32" +import ( + "github.com/chewxy/math32" + "github.com/juju/errors" + "github.com/matttproud/golang_protobuf_extensions/pbutil" + "github.com/zhenghaoz/gorse/protocol" + "io" + "os" + "reflect" + "strconv" +) type Layer interface { Parameters() []*Tensor @@ -23,24 +32,24 @@ type Layer interface { type Model Layer -type linearLayer struct { - w *Tensor - b *Tensor +type LinearLayer struct { + W *Tensor + B *Tensor } func NewLinear(in, out int) Layer { - return &linearLayer{ - w: Normal(0, 1.0/math32.Sqrt(float32(in)), in, out).RequireGrad(), - b: Zeros(out).RequireGrad(), + return &LinearLayer{ + W: Normal(0, 1.0/math32.Sqrt(float32(in)), in, out).RequireGrad(), + B: Zeros(out).RequireGrad(), } } -func (l *linearLayer) Forward(x *Tensor) *Tensor { - return Add(MatMul(x, l.w), l.b) +func (l *LinearLayer) Forward(x *Tensor) *Tensor { + return Add(MatMul(x, l.W), l.B) } -func (l *linearLayer) Parameters() []*Tensor { - return []*Tensor{l.w, l.b} +func (l *LinearLayer) Parameters() []*Tensor { + return []*Tensor{l.W, l.B} } type flattenLayer struct{} @@ -57,23 +66,23 @@ func (f *flattenLayer) Forward(x *Tensor) *Tensor { return Flatten(x) } -type embeddingLayer struct { - w *Tensor +type EmbeddingLayer struct { + W *Tensor } func NewEmbedding(n int, shape ...int) Layer { wShape := append([]int{n}, shape...) - return &embeddingLayer{ - w: Rand(wShape...), + return &EmbeddingLayer{ + W: Rand(wShape...), } } -func (e *embeddingLayer) Parameters() []*Tensor { - return []*Tensor{e.w} +func (e *EmbeddingLayer) Parameters() []*Tensor { + return []*Tensor{e.W} } -func (e *embeddingLayer) Forward(x *Tensor) *Tensor { - return Embedding(e.w, x) +func (e *EmbeddingLayer) Forward(x *Tensor) *Tensor { + return Embedding(e.W, x) } type sigmoidLayer struct{} @@ -105,24 +114,133 @@ func (r *reluLayer) Forward(x *Tensor) *Tensor { } type Sequential struct { - layers []Layer + Layers []Layer } func NewSequential(layers ...Layer) Model { - return &Sequential{layers: layers} + return &Sequential{Layers: layers} } func (s *Sequential) Parameters() []*Tensor { var params []*Tensor - for _, l := range s.layers { + for _, l := range s.Layers { params = append(params, l.Parameters()...) } return params } func (s *Sequential) Forward(x *Tensor) *Tensor { - for _, l := range s.layers { + for _, l := range s.Layers { x = l.Forward(x) } return x } + +func Save[T Model](o T, path string) error { + // Open file + file, err := os.Create(path) + if err != nil { + return err + } + defer file.Close() + + // Save function + var save func(o any, key []string) error + save = func(o any, key []string) error { + switch typed := o.(type) { + case *Tensor: + pb := typed.toPB() + pb.Key = key + _, err = pbutil.WriteDelimited(file, pb) + if err != nil { + return err + } + default: + tp := reflect.TypeOf(o) + if tp.Kind() == reflect.Ptr { + return save(reflect.ValueOf(o).Elem().Interface(), key) + } else if tp.Kind() == reflect.Struct { + for i := 0; i < tp.NumField(); i++ { + field := tp.Field(i) + newKey := make([]string, len(key)) + copy(newKey, key) + newKey = append(newKey, field.Name) + if err = save(reflect.ValueOf(o).Field(i).Interface(), append(key, field.Name)); err != nil { + return err + } + } + } else if tp.Kind() == reflect.Slice { + for i := 0; i < reflect.ValueOf(o).Len(); i++ { + newKey := make([]string, len(key)) + copy(newKey, key) + newKey = append(newKey, strconv.Itoa(i)) + if err = save(reflect.ValueOf(o).Index(i).Interface(), newKey); err != nil { + return err + } + } + } else { + return errors.New("unexpected type") + } + } + return nil + } + return save(o, nil) +} + +func Load[T Model](o T, path string) error { + // Open file + file, err := os.Open(path) + if err != nil { + return err + } + + // Place function + var place func(o any, key []string, pb *protocol.Tensor) error + place = func(o any, key []string, pb *protocol.Tensor) error { + switch typed := o.(type) { + case *Tensor: + typed.fromPB(pb) + default: + tp := reflect.TypeOf(o) + if tp.Kind() == reflect.Ptr { + return place(reflect.ValueOf(o).Elem().Interface(), key, pb) + } else if tp.Kind() == reflect.Struct { + field := reflect.ValueOf(o).FieldByName(key[0]) + if field.IsValid() { + if err := place(field.Interface(), key[1:], pb); err != nil { + return err + } + } + } else if tp.Kind() == reflect.Slice { + index, err := strconv.Atoi(key[0]) + if err != nil { + return err + } + elem := reflect.ValueOf(o).Index(index) + if elem.IsValid() { + if err := place(elem.Interface(), key[1:], pb); err != nil { + return err + } + } + } else { + return errors.New("unexpected type") + } + } + return nil + } + + // Read data + for { + pb := new(protocol.Tensor) + if _, err = pbutil.ReadDelimited(file, pb); err != nil { + if errors.Is(err, io.EOF) { + break + } + return err + } + if err = place(o, pb.Key, pb); err != nil { + return err + } + } + return nil +} diff --git a/common/nn/nn_test.go b/common/nn/nn_test.go index bfcc751e6..41b3c82bc 100644 --- a/common/nn/nn_test.go +++ b/common/nn/nn_test.go @@ -18,6 +18,7 @@ import ( "bufio" "encoding/csv" "fmt" + "math/rand" "os" "path/filepath" "strconv" @@ -68,8 +69,8 @@ func TestNeuralNetwork(t *testing.T) { NewSigmoid(), NewLinear(10, 1), ) - NormalInit(model.(*Sequential).layers[0].(*linearLayer).w, 0, 0.01) - NormalInit(model.(*Sequential).layers[2].(*linearLayer).w, 0, 0.01) + NormalInit(model.(*Sequential).Layers[0].(*LinearLayer).W, 0, 0.01) + NormalInit(model.(*Sequential).Layers[2].(*LinearLayer).W, 0, 0.01) optimizer := NewSGD(model.Parameters(), 0.2) var l float32 @@ -254,3 +255,65 @@ func TestMNIST(t *testing.T) { precision /= float32(len(test.B.data)) assert.Greater(t, float64(precision), 0.92) } + +func spiral() (*Tensor, *Tensor, error) { + numData, numClass, inputDim := 100, 3, 2 + dataSize := numClass * numData + x := Zeros(dataSize, inputDim) + t := Zeros(dataSize) + + for j := 0; j < numClass; j++ { + for i := 0; i < numData; i++ { + rate := float32(i) / float32(numData) + radius := 1.0 * rate + theta := float32(j)*4.0 + 4.0*rate + float32(rand.NormFloat64())*0.2 + ix := numData*j + i + x.data[ix*inputDim] = radius * math32.Sin(theta) + x.data[ix*inputDim+1] = radius * math32.Cos(theta) + t.data[ix] = float32(j) + } + } + + indices := rand.Perm(dataSize) + x = x.SliceIndices(indices...) + t = t.SliceIndices(indices...) + return x, t, nil +} + +func TestSaveAndLoad(t *testing.T) { + x, y, err := spiral() + assert.NoError(t, err) + + model := NewSequential( + NewLinear(2, 10), + NewSigmoid(), + NewLinear(10, 3), + ) + optimizer := NewAdam(model.Parameters(), 0.01) + + var expected float32 + for i := 0; i < 300; i++ { + yPred := model.Forward(x) + loss := SoftmaxCrossEntropy(yPred, y) + + optimizer.ZeroGrad() + loss.Backward() + + optimizer.Step() + expected = loss.data[0] + } + + modelPath := filepath.Join(os.TempDir(), "spiral.nn") + err = Save(model, modelPath) + assert.NoError(t, err) + modelLoaded := NewSequential( + NewLinear(2, 10), + NewSigmoid(), + NewLinear(10, 3), + ) + err = Load(modelLoaded, modelPath) + assert.NoError(t, err) + yPred := modelLoaded.Forward(x) + loss := SoftmaxCrossEntropy(yPred, y) + assert.InDelta(t, float64(expected), float64(loss.data[0]), 0.01) +} diff --git a/common/nn/tensor.go b/common/nn/tensor.go index 695236ea0..962e70d0b 100644 --- a/common/nn/tensor.go +++ b/common/nn/tensor.go @@ -26,6 +26,7 @@ import ( "github.com/google/uuid" "github.com/samber/lo" "github.com/zhenghaoz/gorse/base/floats" + "github.com/zhenghaoz/gorse/protocol" "golang.org/x/exp/slices" ) @@ -186,6 +187,23 @@ func (t *Tensor) Slice(start, end int) *Tensor { } } +func (t *Tensor) SliceIndices(indices ...int) *Tensor { + shape := []int{len(indices)} + subSize := 1 + for i := range t.shape[1:] { + shape = append(shape, t.shape[i+1]) + subSize *= t.shape[i+1] + } + data := make([]float32, len(indices)*subSize) + for i, index := range indices { + copy(data[i*subSize:(i+1)*subSize], t.data[index*subSize:(index+1)*subSize]) + } + return &Tensor{ + data: data, + shape: shape, + } +} + // Get returns the value of the tensor at the given indices. func (t *Tensor) Get(indices ...int) float32 { if len(indices) != len(t.shape) { @@ -751,6 +769,21 @@ func (t *Tensor) argmax() []int { return indices } +func (t *Tensor) toPB() *protocol.Tensor { + return &protocol.Tensor{ + Shape: lo.Map(t.shape, func(i, _ int) int32 { return int32(i) }), + Data: t.data, + } +} + +func (t *Tensor) fromPB(pb *protocol.Tensor) { + t.shape = make([]int, len(pb.Shape)) + for i := range t.shape { + t.shape[i] = int(pb.Shape[i]) + } + t.data = pb.Data +} + func NormalInit(t *Tensor, mean, std float32) { for i := range t.data { t.data[i] = float32(rand.NormFloat64())*(std) + (mean) diff --git a/common/nn/tensor_test.go b/common/nn/tensor_test.go index 309a23809..23ec2075f 100644 --- a/common/nn/tensor_test.go +++ b/common/nn/tensor_test.go @@ -33,6 +33,13 @@ func TestTensor_Slice(t *testing.T) { } } +func TestTensor_SliceIndices(t *testing.T) { + x := NewTensor([]float32{1, 2, 3, 4, 5, 6}, 3, 2) + y := x.SliceIndices(2, 0) + assert.Equal(t, []int{2, 2}, y.Shape()) + assert.Equal(t, []float32{5, 6, 1, 2}, y.Data()) +} + func TestTensor_Max(t *testing.T) { x := NewVariable([]float32{3, 2, 5, 6, 0, 0}, 6) y := x.max(0, false) diff --git a/protocol/tls.go b/common/util/tls.go similarity index 99% rename from protocol/tls.go rename to common/util/tls.go index e71170326..2bc2696aa 100644 --- a/protocol/tls.go +++ b/common/util/tls.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package protocol +package util import ( "crypto/tls" diff --git a/master/master.go b/master/master.go index c96c05c81..05a102e70 100644 --- a/master/master.go +++ b/master/master.go @@ -36,6 +36,7 @@ import ( "github.com/zhenghaoz/gorse/base/progress" "github.com/zhenghaoz/gorse/base/sizeof" "github.com/zhenghaoz/gorse/base/task" + "github.com/zhenghaoz/gorse/common/util" "github.com/zhenghaoz/gorse/config" "github.com/zhenghaoz/gorse/model" "github.com/zhenghaoz/gorse/model/click" @@ -267,7 +268,7 @@ func (m *Master) Serve() { zap.String("ssl_key", m.Config.Master.SSLKey)) opts := []grpc.ServerOption{grpc.MaxSendMsgSize(math.MaxInt)} if m.Config.Master.SSLMode { - c, err := protocol.NewServerCreds(&protocol.TLSConfig{ + c, err := util.NewServerCreds(&util.TLSConfig{ SSLCA: m.Config.Master.SSLCA, SSLCert: m.Config.Master.SSLCert, SSLKey: m.Config.Master.SSLKey, diff --git a/master/rpc_test.go b/master/rpc_test.go index a32ed1d5f..f3221aefd 100644 --- a/master/rpc_test.go +++ b/master/rpc_test.go @@ -27,6 +27,8 @@ import ( "github.com/madflojo/testcerts" "github.com/stretchr/testify/assert" "github.com/zhenghaoz/gorse/base/progress" + "github.com/zhenghaoz/gorse/common/encoding" + "github.com/zhenghaoz/gorse/common/util" "github.com/zhenghaoz/gorse/config" "github.com/zhenghaoz/gorse/model" "github.com/zhenghaoz/gorse/model/click" @@ -91,11 +93,11 @@ func (m *mockMasterRPC) Start(t *testing.T) { assert.NoError(t, err) } -func (m *mockMasterRPC) StartTLS(t *testing.T, o *protocol.TLSConfig) { +func (m *mockMasterRPC) StartTLS(t *testing.T, o *util.TLSConfig) { listen, err := net.Listen("tcp", ":0") assert.NoError(t, err) m.addr <- listen.Addr().String() - creds, err := protocol.NewServerCreds(&protocol.TLSConfig{ + creds, err := util.NewServerCreds(&util.TLSConfig{ SSLCA: o.SSLCA, SSLCert: o.SSLCert, SSLKey: o.SSLKey, @@ -141,14 +143,14 @@ func TestRPC(t *testing.T) { // test get click model clickModelReceiver, err := client.GetClickModel(ctx, &protocol.VersionInfo{Version: 456}) assert.NoError(t, err) - clickModel, err := protocol.UnmarshalClickModel(clickModelReceiver) + clickModel, err := encoding.UnmarshalClickModel(clickModelReceiver) assert.NoError(t, err) assert.Equal(t, rpcServer.ClickModel, clickModel) // test get ranking model rankingModelReceiver, err := client.GetRankingModel(ctx, &protocol.VersionInfo{Version: 123}) assert.NoError(t, err) - rankingModel, err := protocol.UnmarshalRankingModel(rankingModelReceiver) + rankingModel, err := encoding.UnmarshalRankingModel(rankingModelReceiver) assert.NoError(t, err) rpcServer.RankingModel.SetParams(rpcServer.RankingModel.GetParams()) assert.Equal(t, rpcServer.RankingModel, rankingModel) @@ -199,7 +201,7 @@ func generateToTempFile(t *testing.T) (string, string, string) { func TestSSL(t *testing.T) { caFile, certFile, keyFile := generateToTempFile(t) - o := &protocol.TLSConfig{ + o := &util.TLSConfig{ SSLCA: caFile, SSLCert: certFile, SSLKey: keyFile, @@ -210,7 +212,7 @@ func TestSSL(t *testing.T) { address := <-rpcServer.addr // success - c, err := protocol.NewClientCreds(o) + c, err := util.NewClientCreds(o) assert.NoError(t, err) conn, err := grpc.Dial(address, grpc.WithTransportCredentials(c)) assert.NoError(t, err) @@ -227,12 +229,12 @@ func TestSSL(t *testing.T) { // certificate mismatch caFile2, certFile2, keyFile2 := generateToTempFile(t) - o2 := &protocol.TLSConfig{ + o2 := &util.TLSConfig{ SSLCA: caFile2, SSLCert: certFile2, SSLKey: keyFile2, } - c, err = protocol.NewClientCreds(o2) + c, err = util.NewClientCreds(o2) assert.NoError(t, err) conn, err = grpc.Dial(address, grpc.WithTransportCredentials(c)) assert.NoError(t, err) diff --git a/protocol/protocol.pb.go b/protocol/protocol.pb.go index 5cf01ea8d..f2647bf7e 100644 --- a/protocol/protocol.pb.go +++ b/protocol/protocol.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 -// protoc v5.29.0 +// protoc-gen-go v1.35.1 +// protoc v5.28.3 // source: protocol.proto package protocol @@ -84,6 +84,67 @@ func (NodeType) EnumDescriptor() ([]byte, []int) { return file_protocol_proto_rawDescGZIP(), []int{0} } +type Tensor struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key []string `protobuf:"bytes,1,rep,name=key,proto3" json:"key,omitempty"` + Shape []int32 `protobuf:"varint,2,rep,packed,name=shape,proto3" json:"shape,omitempty"` + Data []float32 `protobuf:"fixed32,3,rep,packed,name=data,proto3" json:"data,omitempty"` +} + +func (x *Tensor) Reset() { + *x = Tensor{} + mi := &file_protocol_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Tensor) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Tensor) ProtoMessage() {} + +func (x *Tensor) ProtoReflect() protoreflect.Message { + mi := &file_protocol_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Tensor.ProtoReflect.Descriptor instead. +func (*Tensor) Descriptor() ([]byte, []int) { + return file_protocol_proto_rawDescGZIP(), []int{0} +} + +func (x *Tensor) GetKey() []string { + if x != nil { + return x.Key + } + return nil +} + +func (x *Tensor) GetShape() []int32 { + if x != nil { + return x.Shape + } + return nil +} + +func (x *Tensor) GetData() []float32 { + if x != nil { + return x.Data + } + return nil +} + type User struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -97,7 +158,7 @@ type User struct { func (x *User) Reset() { *x = User{} - mi := &file_protocol_proto_msgTypes[0] + mi := &file_protocol_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -109,7 +170,7 @@ func (x *User) String() string { func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[0] + mi := &file_protocol_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -122,7 +183,7 @@ func (x *User) ProtoReflect() protoreflect.Message { // Deprecated: Use User.ProtoReflect.Descriptor instead. func (*User) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{0} + return file_protocol_proto_rawDescGZIP(), []int{1} } func (x *User) GetUserId() string { @@ -169,7 +230,7 @@ type Item struct { func (x *Item) Reset() { *x = Item{} - mi := &file_protocol_proto_msgTypes[1] + mi := &file_protocol_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -181,7 +242,7 @@ func (x *Item) String() string { func (*Item) ProtoMessage() {} func (x *Item) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[1] + mi := &file_protocol_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -194,7 +255,7 @@ func (x *Item) ProtoReflect() protoreflect.Message { // Deprecated: Use Item.ProtoReflect.Descriptor instead. func (*Item) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{1} + return file_protocol_proto_rawDescGZIP(), []int{2} } func (x *Item) GetNamespace() string { @@ -261,7 +322,7 @@ type Feedback struct { func (x *Feedback) Reset() { *x = Feedback{} - mi := &file_protocol_proto_msgTypes[2] + mi := &file_protocol_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -273,7 +334,7 @@ func (x *Feedback) String() string { func (*Feedback) ProtoMessage() {} func (x *Feedback) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[2] + mi := &file_protocol_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -286,7 +347,7 @@ func (x *Feedback) ProtoReflect() protoreflect.Message { // Deprecated: Use Feedback.ProtoReflect.Descriptor instead. func (*Feedback) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{2} + return file_protocol_proto_rawDescGZIP(), []int{3} } func (x *Feedback) GetNamespace() string { @@ -346,7 +407,7 @@ type Meta struct { func (x *Meta) Reset() { *x = Meta{} - mi := &file_protocol_proto_msgTypes[3] + mi := &file_protocol_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -358,7 +419,7 @@ func (x *Meta) String() string { func (*Meta) ProtoMessage() {} func (x *Meta) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[3] + mi := &file_protocol_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -371,7 +432,7 @@ func (x *Meta) ProtoReflect() protoreflect.Message { // Deprecated: Use Meta.ProtoReflect.Descriptor instead. func (*Meta) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{3} + return file_protocol_proto_rawDescGZIP(), []int{4} } func (x *Meta) GetConfig() string { @@ -426,7 +487,7 @@ type Fragment struct { func (x *Fragment) Reset() { *x = Fragment{} - mi := &file_protocol_proto_msgTypes[4] + mi := &file_protocol_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -438,7 +499,7 @@ func (x *Fragment) String() string { func (*Fragment) ProtoMessage() {} func (x *Fragment) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[4] + mi := &file_protocol_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -451,7 +512,7 @@ func (x *Fragment) ProtoReflect() protoreflect.Message { // Deprecated: Use Fragment.ProtoReflect.Descriptor instead. func (*Fragment) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{4} + return file_protocol_proto_rawDescGZIP(), []int{5} } func (x *Fragment) GetData() []byte { @@ -471,7 +532,7 @@ type VersionInfo struct { func (x *VersionInfo) Reset() { *x = VersionInfo{} - mi := &file_protocol_proto_msgTypes[5] + mi := &file_protocol_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -483,7 +544,7 @@ func (x *VersionInfo) String() string { func (*VersionInfo) ProtoMessage() {} func (x *VersionInfo) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[5] + mi := &file_protocol_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -496,7 +557,7 @@ func (x *VersionInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionInfo.ProtoReflect.Descriptor instead. func (*VersionInfo) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{5} + return file_protocol_proto_rawDescGZIP(), []int{6} } func (x *VersionInfo) GetVersion() int64 { @@ -519,7 +580,7 @@ type NodeInfo struct { func (x *NodeInfo) Reset() { *x = NodeInfo{} - mi := &file_protocol_proto_msgTypes[6] + mi := &file_protocol_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -531,7 +592,7 @@ func (x *NodeInfo) String() string { func (*NodeInfo) ProtoMessage() {} func (x *NodeInfo) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[6] + mi := &file_protocol_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -544,7 +605,7 @@ func (x *NodeInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use NodeInfo.ProtoReflect.Descriptor instead. func (*NodeInfo) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{6} + return file_protocol_proto_rawDescGZIP(), []int{7} } func (x *NodeInfo) GetNodeType() NodeType { @@ -592,7 +653,7 @@ type Progress struct { func (x *Progress) Reset() { *x = Progress{} - mi := &file_protocol_proto_msgTypes[7] + mi := &file_protocol_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -604,7 +665,7 @@ func (x *Progress) String() string { func (*Progress) ProtoMessage() {} func (x *Progress) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[7] + mi := &file_protocol_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -617,7 +678,7 @@ func (x *Progress) ProtoReflect() protoreflect.Message { // Deprecated: Use Progress.ProtoReflect.Descriptor instead. func (*Progress) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{7} + return file_protocol_proto_rawDescGZIP(), []int{8} } func (x *Progress) GetTracer() string { @@ -686,7 +747,7 @@ type PushProgressRequest struct { func (x *PushProgressRequest) Reset() { *x = PushProgressRequest{} - mi := &file_protocol_proto_msgTypes[8] + mi := &file_protocol_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -698,7 +759,7 @@ func (x *PushProgressRequest) String() string { func (*PushProgressRequest) ProtoMessage() {} func (x *PushProgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[8] + mi := &file_protocol_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -711,7 +772,7 @@ func (x *PushProgressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PushProgressRequest.ProtoReflect.Descriptor instead. func (*PushProgressRequest) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{8} + return file_protocol_proto_rawDescGZIP(), []int{9} } func (x *PushProgressRequest) GetProgress() []*Progress { @@ -729,7 +790,7 @@ type PushProgressResponse struct { func (x *PushProgressResponse) Reset() { *x = PushProgressResponse{} - mi := &file_protocol_proto_msgTypes[9] + mi := &file_protocol_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -741,7 +802,7 @@ func (x *PushProgressResponse) String() string { func (*PushProgressResponse) ProtoMessage() {} func (x *PushProgressResponse) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[9] + mi := &file_protocol_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -754,7 +815,7 @@ func (x *PushProgressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PushProgressResponse.ProtoReflect.Descriptor instead. func (*PushProgressResponse) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{9} + return file_protocol_proto_rawDescGZIP(), []int{10} } type PingRequest struct { @@ -765,7 +826,7 @@ type PingRequest struct { func (x *PingRequest) Reset() { *x = PingRequest{} - mi := &file_protocol_proto_msgTypes[10] + mi := &file_protocol_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -777,7 +838,7 @@ func (x *PingRequest) String() string { func (*PingRequest) ProtoMessage() {} func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[10] + mi := &file_protocol_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -790,7 +851,7 @@ func (x *PingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. func (*PingRequest) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{10} + return file_protocol_proto_rawDescGZIP(), []int{11} } type PingResponse struct { @@ -801,7 +862,7 @@ type PingResponse struct { func (x *PingResponse) Reset() { *x = PingResponse{} - mi := &file_protocol_proto_msgTypes[11] + mi := &file_protocol_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -813,7 +874,7 @@ func (x *PingResponse) String() string { func (*PingResponse) ProtoMessage() {} func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[11] + mi := &file_protocol_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -826,7 +887,7 @@ func (x *PingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. func (*PingResponse) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{11} + return file_protocol_proto_rawDescGZIP(), []int{12} } type UploadBlobRequest struct { @@ -841,7 +902,7 @@ type UploadBlobRequest struct { func (x *UploadBlobRequest) Reset() { *x = UploadBlobRequest{} - mi := &file_protocol_proto_msgTypes[12] + mi := &file_protocol_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -853,7 +914,7 @@ func (x *UploadBlobRequest) String() string { func (*UploadBlobRequest) ProtoMessage() {} func (x *UploadBlobRequest) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[12] + mi := &file_protocol_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -866,7 +927,7 @@ func (x *UploadBlobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadBlobRequest.ProtoReflect.Descriptor instead. func (*UploadBlobRequest) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{12} + return file_protocol_proto_rawDescGZIP(), []int{13} } func (x *UploadBlobRequest) GetName() string { @@ -898,7 +959,7 @@ type UploadBlobResponse struct { func (x *UploadBlobResponse) Reset() { *x = UploadBlobResponse{} - mi := &file_protocol_proto_msgTypes[13] + mi := &file_protocol_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -910,7 +971,7 @@ func (x *UploadBlobResponse) String() string { func (*UploadBlobResponse) ProtoMessage() {} func (x *UploadBlobResponse) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[13] + mi := &file_protocol_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -923,7 +984,7 @@ func (x *UploadBlobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadBlobResponse.ProtoReflect.Descriptor instead. func (*UploadBlobResponse) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{13} + return file_protocol_proto_rawDescGZIP(), []int{14} } type FetchBlobRequest struct { @@ -936,7 +997,7 @@ type FetchBlobRequest struct { func (x *FetchBlobRequest) Reset() { *x = FetchBlobRequest{} - mi := &file_protocol_proto_msgTypes[14] + mi := &file_protocol_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -948,7 +1009,7 @@ func (x *FetchBlobRequest) String() string { func (*FetchBlobRequest) ProtoMessage() {} func (x *FetchBlobRequest) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[14] + mi := &file_protocol_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -961,7 +1022,7 @@ func (x *FetchBlobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchBlobRequest.ProtoReflect.Descriptor instead. func (*FetchBlobRequest) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{14} + return file_protocol_proto_rawDescGZIP(), []int{15} } func (x *FetchBlobRequest) GetName() string { @@ -981,7 +1042,7 @@ type FetchBlobResponse struct { func (x *FetchBlobResponse) Reset() { *x = FetchBlobResponse{} - mi := &file_protocol_proto_msgTypes[15] + mi := &file_protocol_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -993,7 +1054,7 @@ func (x *FetchBlobResponse) String() string { func (*FetchBlobResponse) ProtoMessage() {} func (x *FetchBlobResponse) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[15] + mi := &file_protocol_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1006,7 +1067,7 @@ func (x *FetchBlobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchBlobResponse.ProtoReflect.Descriptor instead. func (*FetchBlobResponse) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{15} + return file_protocol_proto_rawDescGZIP(), []int{16} } func (x *FetchBlobResponse) GetTimestamp() *timestamppb.Timestamp { @@ -1026,7 +1087,7 @@ type DownloadBlobRequest struct { func (x *DownloadBlobRequest) Reset() { *x = DownloadBlobRequest{} - mi := &file_protocol_proto_msgTypes[16] + mi := &file_protocol_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1038,7 +1099,7 @@ func (x *DownloadBlobRequest) String() string { func (*DownloadBlobRequest) ProtoMessage() {} func (x *DownloadBlobRequest) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[16] + mi := &file_protocol_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1051,7 +1112,7 @@ func (x *DownloadBlobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DownloadBlobRequest.ProtoReflect.Descriptor instead. func (*DownloadBlobRequest) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{16} + return file_protocol_proto_rawDescGZIP(), []int{17} } func (x *DownloadBlobRequest) GetName() string { @@ -1071,7 +1132,7 @@ type DownloadBlobResponse struct { func (x *DownloadBlobResponse) Reset() { *x = DownloadBlobResponse{} - mi := &file_protocol_proto_msgTypes[17] + mi := &file_protocol_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1083,7 +1144,7 @@ func (x *DownloadBlobResponse) String() string { func (*DownloadBlobResponse) ProtoMessage() {} func (x *DownloadBlobResponse) ProtoReflect() protoreflect.Message { - mi := &file_protocol_proto_msgTypes[17] + mi := &file_protocol_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1096,7 +1157,7 @@ func (x *DownloadBlobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DownloadBlobResponse.ProtoReflect.Descriptor instead. func (*DownloadBlobResponse) Descriptor() ([]byte, []int) { - return file_protocol_proto_rawDescGZIP(), []int{17} + return file_protocol_proto_rawDescGZIP(), []int{18} } func (x *DownloadBlobResponse) GetData() []byte { @@ -1112,150 +1173,154 @@ var file_protocol_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6f, 0x0a, 0x04, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1c, - 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x22, 0xe6, 0x01, 0x0a, - 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x69, 0x73, 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x69, 0x73, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, - 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, - 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x08, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, - 0x63, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, - 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, - 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x04, - 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a, 0x15, - 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x72, 0x61, 0x6e, - 0x6b, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x63, - 0x6c, 0x69, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x0e, 0x0a, 0x02, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6d, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x6f, - 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x77, 0x6f, 0x72, - 0x6b, 0x65, 0x72, 0x73, 0x22, 0x1e, 0x0a, 0x08, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x22, 0x27, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x92, 0x01, - 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x09, 0x6e, 0x6f, - 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, - 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, - 0x25, 0x0a, 0x0e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x73, - 0x68, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x13, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, - 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x08, - 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x16, 0x0a, 0x14, - 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 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, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x26, 0x0a, 0x10, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x6c, 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, 0x22, 0x4d, 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x44, 0x0a, 0x06, 0x54, + 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x70, 0x65, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x05, 0x73, 0x68, 0x61, 0x70, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x02, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x22, 0x6f, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, + 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, + 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, + 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, + 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x08, + 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, + 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x29, 0x0a, 0x13, 0x44, 0x6f, 0x77, 0x6e, 0x6c, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, + 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x13, 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x11, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x22, 0x1e, 0x0a, 0x08, 0x46, 0x72, + 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x27, 0x0a, 0x0b, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x22, 0x92, 0x01, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x2f, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x4e, + 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, + 0x6e, 0x69, 0x73, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x13, 0x50, + 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 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, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, - 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x2e, - 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, - 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x32, 0x8c, - 0x02, 0x0a, 0x06, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x07, 0x47, 0x65, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, - 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x52, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x15, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, - 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x0d, - 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x15, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, - 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4f, 0x0a, 0x0c, - 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, - 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xf3, 0x01, - 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x4b, 0x0a, 0x0a, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x46, 0x0a, 0x09, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x65, 0x74, - 0x63, 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x51, 0x0a, 0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, - 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x44, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, - 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x30, 0x01, 0x42, 0x25, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x7a, 0x68, 0x65, 0x6e, 0x67, 0x68, 0x61, 0x6f, 0x7a, 0x2f, 0x67, 0x6f, 0x72, 0x73, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, + 0x6c, 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, 0x22, 0x4d, + 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x29, 0x0a, + 0x13, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 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, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x2a, 0x2e, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, + 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x10, 0x02, 0x32, 0x8c, 0x02, 0x0a, 0x06, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, + 0x2f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x00, + 0x12, 0x40, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x4f, 0x0a, 0x0c, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, + 0x73, 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x73, + 0x68, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x32, 0xf3, 0x01, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x12, 0x4b, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x12, + 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, + 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x46, + 0x0a, 0x09, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1a, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x6c, 0x6f, 0x62, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, + 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x25, 0x5a, 0x23, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x7a, 0x68, 0x65, 0x6e, 0x67, 0x68, 0x61, 0x6f, + 0x7a, 0x2f, 0x67, 0x6f, 0x72, 0x73, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1271,50 +1336,51 @@ func file_protocol_proto_rawDescGZIP() []byte { } var file_protocol_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_protocol_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_protocol_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_protocol_proto_goTypes = []any{ (NodeType)(0), // 0: protocol.NodeType - (*User)(nil), // 1: protocol.User - (*Item)(nil), // 2: protocol.Item - (*Feedback)(nil), // 3: protocol.Feedback - (*Meta)(nil), // 4: protocol.Meta - (*Fragment)(nil), // 5: protocol.Fragment - (*VersionInfo)(nil), // 6: protocol.VersionInfo - (*NodeInfo)(nil), // 7: protocol.NodeInfo - (*Progress)(nil), // 8: protocol.Progress - (*PushProgressRequest)(nil), // 9: protocol.PushProgressRequest - (*PushProgressResponse)(nil), // 10: protocol.PushProgressResponse - (*PingRequest)(nil), // 11: protocol.PingRequest - (*PingResponse)(nil), // 12: protocol.PingResponse - (*UploadBlobRequest)(nil), // 13: protocol.UploadBlobRequest - (*UploadBlobResponse)(nil), // 14: protocol.UploadBlobResponse - (*FetchBlobRequest)(nil), // 15: protocol.FetchBlobRequest - (*FetchBlobResponse)(nil), // 16: protocol.FetchBlobResponse - (*DownloadBlobRequest)(nil), // 17: protocol.DownloadBlobRequest - (*DownloadBlobResponse)(nil), // 18: protocol.DownloadBlobResponse - (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp + (*Tensor)(nil), // 1: protocol.Tensor + (*User)(nil), // 2: protocol.User + (*Item)(nil), // 3: protocol.Item + (*Feedback)(nil), // 4: protocol.Feedback + (*Meta)(nil), // 5: protocol.Meta + (*Fragment)(nil), // 6: protocol.Fragment + (*VersionInfo)(nil), // 7: protocol.VersionInfo + (*NodeInfo)(nil), // 8: protocol.NodeInfo + (*Progress)(nil), // 9: protocol.Progress + (*PushProgressRequest)(nil), // 10: protocol.PushProgressRequest + (*PushProgressResponse)(nil), // 11: protocol.PushProgressResponse + (*PingRequest)(nil), // 12: protocol.PingRequest + (*PingResponse)(nil), // 13: protocol.PingResponse + (*UploadBlobRequest)(nil), // 14: protocol.UploadBlobRequest + (*UploadBlobResponse)(nil), // 15: protocol.UploadBlobResponse + (*FetchBlobRequest)(nil), // 16: protocol.FetchBlobRequest + (*FetchBlobResponse)(nil), // 17: protocol.FetchBlobResponse + (*DownloadBlobRequest)(nil), // 18: protocol.DownloadBlobRequest + (*DownloadBlobResponse)(nil), // 19: protocol.DownloadBlobResponse + (*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp } var file_protocol_proto_depIdxs = []int32{ - 19, // 0: protocol.Item.timestamp:type_name -> google.protobuf.Timestamp - 19, // 1: protocol.Feedback.timestamp:type_name -> google.protobuf.Timestamp + 20, // 0: protocol.Item.timestamp:type_name -> google.protobuf.Timestamp + 20, // 1: protocol.Feedback.timestamp:type_name -> google.protobuf.Timestamp 0, // 2: protocol.NodeInfo.node_type:type_name -> protocol.NodeType - 8, // 3: protocol.PushProgressRequest.progress:type_name -> protocol.Progress - 19, // 4: protocol.UploadBlobRequest.timestamp:type_name -> google.protobuf.Timestamp - 19, // 5: protocol.FetchBlobResponse.timestamp:type_name -> google.protobuf.Timestamp - 7, // 6: protocol.Master.GetMeta:input_type -> protocol.NodeInfo - 6, // 7: protocol.Master.GetRankingModel:input_type -> protocol.VersionInfo - 6, // 8: protocol.Master.GetClickModel:input_type -> protocol.VersionInfo - 9, // 9: protocol.Master.PushProgress:input_type -> protocol.PushProgressRequest - 13, // 10: protocol.BlobStore.UploadBlob:input_type -> protocol.UploadBlobRequest - 15, // 11: protocol.BlobStore.FetchBlob:input_type -> protocol.FetchBlobRequest - 17, // 12: protocol.BlobStore.DownloadBlob:input_type -> protocol.DownloadBlobRequest - 4, // 13: protocol.Master.GetMeta:output_type -> protocol.Meta - 5, // 14: protocol.Master.GetRankingModel:output_type -> protocol.Fragment - 5, // 15: protocol.Master.GetClickModel:output_type -> protocol.Fragment - 10, // 16: protocol.Master.PushProgress:output_type -> protocol.PushProgressResponse - 14, // 17: protocol.BlobStore.UploadBlob:output_type -> protocol.UploadBlobResponse - 16, // 18: protocol.BlobStore.FetchBlob:output_type -> protocol.FetchBlobResponse - 18, // 19: protocol.BlobStore.DownloadBlob:output_type -> protocol.DownloadBlobResponse + 9, // 3: protocol.PushProgressRequest.progress:type_name -> protocol.Progress + 20, // 4: protocol.UploadBlobRequest.timestamp:type_name -> google.protobuf.Timestamp + 20, // 5: protocol.FetchBlobResponse.timestamp:type_name -> google.protobuf.Timestamp + 8, // 6: protocol.Master.GetMeta:input_type -> protocol.NodeInfo + 7, // 7: protocol.Master.GetRankingModel:input_type -> protocol.VersionInfo + 7, // 8: protocol.Master.GetClickModel:input_type -> protocol.VersionInfo + 10, // 9: protocol.Master.PushProgress:input_type -> protocol.PushProgressRequest + 14, // 10: protocol.BlobStore.UploadBlob:input_type -> protocol.UploadBlobRequest + 16, // 11: protocol.BlobStore.FetchBlob:input_type -> protocol.FetchBlobRequest + 18, // 12: protocol.BlobStore.DownloadBlob:input_type -> protocol.DownloadBlobRequest + 5, // 13: protocol.Master.GetMeta:output_type -> protocol.Meta + 6, // 14: protocol.Master.GetRankingModel:output_type -> protocol.Fragment + 6, // 15: protocol.Master.GetClickModel:output_type -> protocol.Fragment + 11, // 16: protocol.Master.PushProgress:output_type -> protocol.PushProgressResponse + 15, // 17: protocol.BlobStore.UploadBlob:output_type -> protocol.UploadBlobResponse + 17, // 18: protocol.BlobStore.FetchBlob:output_type -> protocol.FetchBlobResponse + 19, // 19: protocol.BlobStore.DownloadBlob:output_type -> protocol.DownloadBlobResponse 13, // [13:20] is the sub-list for method output_type 6, // [6:13] is the sub-list for method input_type 6, // [6:6] is the sub-list for extension type_name @@ -1333,7 +1399,7 @@ func file_protocol_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_protocol_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 2, }, diff --git a/protocol/protocol.proto b/protocol/protocol.proto index f607d71e0..70397d2a3 100644 --- a/protocol/protocol.proto +++ b/protocol/protocol.proto @@ -20,6 +20,12 @@ package protocol; import "google/protobuf/timestamp.proto"; +message Tensor { + repeated string key = 1; + repeated int32 shape = 2; + repeated float data = 3; +} + message User { string user_id = 1; bytes labels = 2; diff --git a/server/server.go b/server/server.go index 1d9dc1a24..9cab28705 100644 --- a/server/server.go +++ b/server/server.go @@ -30,6 +30,7 @@ import ( "github.com/zhenghaoz/gorse/base" "github.com/zhenghaoz/gorse/base/log" "github.com/zhenghaoz/gorse/cmd/version" + "github.com/zhenghaoz/gorse/common/util" "github.com/zhenghaoz/gorse/config" "github.com/zhenghaoz/gorse/protocol" "github.com/zhenghaoz/gorse/storage" @@ -55,7 +56,7 @@ type Server struct { serverName string masterHost string masterPort int - tlsConfig *protocol.TLSConfig + tlsConfig *util.TLSConfig testMode bool cacheFile string } @@ -67,7 +68,7 @@ func NewServer( serverHost string, serverPort int, cacheFile string, - tlsConfig *protocol.TLSConfig, + tlsConfig *util.TLSConfig, ) *Server { s := &Server{ masterHost: masterHost, @@ -115,7 +116,7 @@ func (s *Server) Serve() { // connect to master var opts []grpc.DialOption if s.tlsConfig != nil { - c, err := protocol.NewClientCreds(s.tlsConfig) + c, err := util.NewClientCreds(s.tlsConfig) if err != nil { log.Logger().Fatal("failed to create credentials", zap.Error(err)) } diff --git a/worker/worker.go b/worker/worker.go index b231c5659..549784c3a 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -43,6 +43,8 @@ import ( "github.com/zhenghaoz/gorse/base/search" "github.com/zhenghaoz/gorse/base/sizeof" "github.com/zhenghaoz/gorse/cmd/version" + encoding2 "github.com/zhenghaoz/gorse/common/encoding" + "github.com/zhenghaoz/gorse/common/util" "github.com/zhenghaoz/gorse/config" "github.com/zhenghaoz/gorse/model/click" "github.com/zhenghaoz/gorse/model/ranking" @@ -85,7 +87,7 @@ type Worker struct { httpPort int masterHost string masterPort int - tlsConfig *protocol.TLSConfig + tlsConfig *util.TLSConfig cacheFile string // database connection path @@ -127,7 +129,7 @@ func NewWorker( jobs int, cacheFile string, managedMode bool, - tlsConfig *protocol.TLSConfig, + tlsConfig *util.TLSConfig, ) *Worker { return &Worker{ rankers: make([]click.FactorizationMachine, jobs), @@ -267,7 +269,7 @@ func (w *Worker) Pull() { log.Logger().Error("failed to pull ranking model", zap.Error(err)) } else { var rankingModel ranking.MatrixFactorization - rankingModel, err = protocol.UnmarshalRankingModel(rankingModelReceiver) + rankingModel, err = encoding2.UnmarshalRankingModel(rankingModelReceiver) if err != nil { log.Logger().Error("failed to unmarshal ranking model", zap.Error(err)) } else { @@ -291,7 +293,7 @@ func (w *Worker) Pull() { log.Logger().Error("failed to pull click model", zap.Error(err)) } else { var clickModel click.FactorizationMachine - clickModel, err = protocol.UnmarshalClickModel(clickModelReceiver) + clickModel, err = encoding2.UnmarshalClickModel(clickModelReceiver) if err != nil { log.Logger().Error("failed to unmarshal click model", zap.Error(err)) } else { @@ -416,7 +418,7 @@ func (w *Worker) Serve() { // connect to master var opts []grpc.DialOption if w.tlsConfig != nil { - c, err := protocol.NewClientCreds(w.tlsConfig) + c, err := util.NewClientCreds(w.tlsConfig) if err != nil { log.Logger().Fatal("failed to create credentials", zap.Error(err)) }