From 3abdb1f1b96e3d9c310353a52264fe6ba3bef2f9 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Mon, 31 Jul 2023 08:04:12 +0000 Subject: [PATCH 01/10] implement StreamListObject and its tests --- apis/docs/v1/docs.md | 31 +- apis/grpc/v1/payload/payload.pb.go | 527 ++++++++++---- apis/grpc/v1/payload/payload_vtproto.pb.go | 688 +++++++++++++++++- apis/grpc/v1/vald/object.pb.go | 43 +- apis/grpc/v1/vald/object_vtproto.pb.go | 65 ++ apis/grpc/v1/vald/vald.go | 7 +- apis/proto/v1/payload/payload.proto | 11 + apis/proto/v1/vald/object.proto | 5 + .../apis/proto/v1/vald/filter.swagger.json | 40 +- .../apis/proto/v1/vald/object.swagger.json | 41 ++ .../apis/proto/v1/vald/search.swagger.json | 46 +- go.mod | 1 + internal/net/grpc/status/status.go | 4 + internal/net/grpc/stream.go | 10 +- internal/net/grpc/stream_test.go | 59 ++ internal/test/mock/grpc_testify_mock.go | 54 ++ pkg/agent/core/ngt/handler/grpc/object.go | 56 ++ .../core/ngt/handler/grpc/object_test.go | 165 ++++- pkg/agent/core/ngt/service/ngt.go | 7 + 19 files changed, 1620 insertions(+), 240 deletions(-) create mode 100644 internal/test/mock/grpc_testify_mock.go diff --git a/apis/docs/v1/docs.md b/apis/docs/v1/docs.md index 24bf7ebea9..f93e8153f4 100644 --- a/apis/docs/v1/docs.md +++ b/apis/docs/v1/docs.md @@ -48,6 +48,9 @@ - [Object.Distance](#payload-v1-Object-Distance) - [Object.ID](#payload-v1-Object-ID) - [Object.IDs](#payload-v1-Object-IDs) + - [Object.List](#payload-v1-Object-List) + - [Object.List.Request](#payload-v1-Object-List-Request) + - [Object.List.Response](#payload-v1-Object-List-Response) - [Object.Location](#payload-v1-Object-Location) - [Object.Locations](#payload-v1-Object-Locations) - [Object.ReshapeVector](#payload-v1-Object-ReshapeVector) @@ -508,6 +511,23 @@ Represent multiple vector IDs. | ----- | ----------------- | -------- | ----------- | | ids | [string](#string) | repeated | | + + +### Object.List + + + +### Object.List.Request + + + +### Object.List.Response + +| Field | Type | Label | Description | +| ------ | ------------------------------------------ | ----- | ----------- | +| vector | [Object.Vector](#payload-v1-Object-Vector) | | | +| status | [google.rpc.Status](#google-rpc-Status) | | | + ### Object.Location @@ -997,11 +1017,12 @@ Upsert service provides ways to insert/update vectors. Object service provides ways to fetch indexed vectors. -| Method Name | Request Type | Response Type | Description | -| --------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -| Exists | [.payload.v1.Object.ID](#payload-v1-Object-ID) | [.payload.v1.Object.ID](#payload-v1-Object-ID) | A method to check whether a specified ID is indexed or not. | -| GetObject | [.payload.v1.Object.VectorRequest](#payload-v1-Object-VectorRequest) | [.payload.v1.Object.Vector](#payload-v1-Object-Vector) | A method to fetch a vector. | -| StreamGetObject | [.payload.v1.Object.VectorRequest](#payload-v1-Object-VectorRequest) stream | [.payload.v1.Object.StreamVector](#payload-v1-Object-StreamVector) stream | A method to fetch vectors by bidirectional streaming. | +| Method Name | Request Type | Response Type | Description | +| ---------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ----------------------------------------------------------- | +| Exists | [.payload.v1.Object.ID](#payload-v1-Object-ID) | [.payload.v1.Object.ID](#payload-v1-Object-ID) | A method to check whether a specified ID is indexed or not. | +| GetObject | [.payload.v1.Object.VectorRequest](#payload-v1-Object-VectorRequest) | [.payload.v1.Object.Vector](#payload-v1-Object-Vector) | A method to fetch a vector. | +| StreamGetObject | [.payload.v1.Object.VectorRequest](#payload-v1-Object-VectorRequest) stream | [.payload.v1.Object.StreamVector](#payload-v1-Object-StreamVector) stream | A method to fetch vectors by bidirectional streaming. | +| StreamListObject | [.payload.v1.Object.List.Request](#payload-v1-Object-List-Request) | [.payload.v1.Object.List.Response](#payload-v1-Object-List-Response) stream | A method to get all the vectors with server streaming | diff --git a/apis/grpc/v1/payload/payload.pb.go b/apis/grpc/v1/payload/payload.pb.go index 710d65aced..ca79c76467 100644 --- a/apis/grpc/v1/payload/payload.pb.go +++ b/apis/grpc/v1/payload/payload.pb.go @@ -3222,6 +3222,163 @@ func (x *Object_Locations) GetLocations() []*Object_Location { return nil } +type Object_List struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Object_List) Reset() { + *x = Object_List{} + if protoimpl.UnsafeEnabled { + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Object_List) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Object_List) ProtoMessage() {} + +func (x *Object_List) ProtoReflect() protoreflect.Message { + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[55] + 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 Object_List.ProtoReflect.Descriptor instead. +func (*Object_List) Descriptor() ([]byte, []int) { + return file_apis_proto_v1_payload_payload_proto_rawDescGZIP(), []int{6, 14} +} + +type Object_List_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Object_List_Request) Reset() { + *x = Object_List_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Object_List_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Object_List_Request) ProtoMessage() {} + +func (x *Object_List_Request) ProtoReflect() protoreflect.Message { + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[56] + 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 Object_List_Request.ProtoReflect.Descriptor instead. +func (*Object_List_Request) Descriptor() ([]byte, []int) { + return file_apis_proto_v1_payload_payload_proto_rawDescGZIP(), []int{6, 14, 0} +} + +type Object_List_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Payload: + // + // *Object_List_Response_Vector + // *Object_List_Response_Status + Payload isObject_List_Response_Payload `protobuf_oneof:"payload"` +} + +func (x *Object_List_Response) Reset() { + *x = Object_List_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Object_List_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Object_List_Response) ProtoMessage() {} + +func (x *Object_List_Response) ProtoReflect() protoreflect.Message { + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[57] + 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 Object_List_Response.ProtoReflect.Descriptor instead. +func (*Object_List_Response) Descriptor() ([]byte, []int) { + return file_apis_proto_v1_payload_payload_proto_rawDescGZIP(), []int{6, 14, 1} +} + +func (m *Object_List_Response) GetPayload() isObject_List_Response_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (x *Object_List_Response) GetVector() *Object_Vector { + if x, ok := x.GetPayload().(*Object_List_Response_Vector); ok { + return x.Vector + } + return nil +} + +func (x *Object_List_Response) GetStatus() *status.Status { + if x, ok := x.GetPayload().(*Object_List_Response_Status); ok { + return x.Status + } + return nil +} + +type isObject_List_Response_Payload interface { + isObject_List_Response_Payload() +} + +type Object_List_Response_Vector struct { + Vector *Object_Vector `protobuf:"bytes,1,opt,name=vector,proto3,oneof"` +} + +type Object_List_Response_Status struct { + Status *status.Status `protobuf:"bytes,2,opt,name=status,proto3,oneof"` +} + +func (*Object_List_Response_Vector) isObject_List_Response_Payload() {} + +func (*Object_List_Response_Status) isObject_List_Response_Payload() {} + // Represent the create index request. type Control_CreateIndexRequest struct { state protoimpl.MessageState @@ -3235,7 +3392,7 @@ type Control_CreateIndexRequest struct { func (x *Control_CreateIndexRequest) Reset() { *x = Control_CreateIndexRequest{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[55] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3248,7 +3405,7 @@ func (x *Control_CreateIndexRequest) String() string { func (*Control_CreateIndexRequest) ProtoMessage() {} func (x *Control_CreateIndexRequest) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[55] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3288,7 +3445,7 @@ type Discoverer_Request struct { func (x *Discoverer_Request) Reset() { *x = Discoverer_Request{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[56] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3301,7 +3458,7 @@ func (x *Discoverer_Request) String() string { func (*Discoverer_Request) ProtoMessage() {} func (x *Discoverer_Request) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[56] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3348,7 +3505,7 @@ type Info_Index struct { func (x *Info_Index) Reset() { *x = Info_Index{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[57] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3361,7 +3518,7 @@ func (x *Info_Index) String() string { func (*Info_Index) ProtoMessage() {} func (x *Info_Index) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[57] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3402,7 +3559,7 @@ type Info_Pod struct { func (x *Info_Pod) Reset() { *x = Info_Pod{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[58] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3415,7 +3572,7 @@ func (x *Info_Pod) String() string { func (*Info_Pod) ProtoMessage() {} func (x *Info_Pod) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[58] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3503,7 +3660,7 @@ type Info_Node struct { func (x *Info_Node) Reset() { *x = Info_Node{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[59] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3516,7 +3673,7 @@ func (x *Info_Node) String() string { func (*Info_Node) ProtoMessage() {} func (x *Info_Node) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[59] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3591,7 +3748,7 @@ type Info_CPU struct { func (x *Info_CPU) Reset() { *x = Info_CPU{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[60] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3604,7 +3761,7 @@ func (x *Info_CPU) String() string { func (*Info_CPU) ProtoMessage() {} func (x *Info_CPU) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[60] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3658,7 +3815,7 @@ type Info_Memory struct { func (x *Info_Memory) Reset() { *x = Info_Memory{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[61] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3671,7 +3828,7 @@ func (x *Info_Memory) String() string { func (*Info_Memory) ProtoMessage() {} func (x *Info_Memory) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[61] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3721,7 +3878,7 @@ type Info_Pods struct { func (x *Info_Pods) Reset() { *x = Info_Pods{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[62] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3734,7 +3891,7 @@ func (x *Info_Pods) String() string { func (*Info_Pods) ProtoMessage() {} func (x *Info_Pods) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[62] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3770,7 +3927,7 @@ type Info_Nodes struct { func (x *Info_Nodes) Reset() { *x = Info_Nodes{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[63] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3783,7 +3940,7 @@ func (x *Info_Nodes) String() string { func (*Info_Nodes) ProtoMessage() {} func (x *Info_Nodes) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[63] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3818,7 +3975,7 @@ type Info_IPs struct { func (x *Info_IPs) Reset() { *x = Info_IPs{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[64] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3831,7 +3988,7 @@ func (x *Info_IPs) String() string { func (*Info_IPs) ProtoMessage() {} func (x *Info_IPs) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[64] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3873,7 +4030,7 @@ type Info_Index_Count struct { func (x *Info_Index_Count) Reset() { *x = Info_Index_Count{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[65] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3886,7 +4043,7 @@ func (x *Info_Index_Count) String() string { func (*Info_Index_Count) ProtoMessage() {} func (x *Info_Index_Count) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[65] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3940,7 +4097,7 @@ type Info_Index_UUID struct { func (x *Info_Index_UUID) Reset() { *x = Info_Index_UUID{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[66] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3953,7 +4110,7 @@ func (x *Info_Index_UUID) String() string { func (*Info_Index_UUID) ProtoMessage() {} func (x *Info_Index_UUID) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[66] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3981,7 +4138,7 @@ type Info_Index_UUID_Committed struct { func (x *Info_Index_UUID_Committed) Reset() { *x = Info_Index_UUID_Committed{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[67] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3994,7 +4151,7 @@ func (x *Info_Index_UUID_Committed) String() string { func (*Info_Index_UUID_Committed) ProtoMessage() {} func (x *Info_Index_UUID_Committed) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[67] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4029,7 +4186,7 @@ type Info_Index_UUID_Uncommitted struct { func (x *Info_Index_UUID_Uncommitted) Reset() { *x = Info_Index_UUID_Uncommitted{} if protoimpl.UnsafeEnabled { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[68] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4042,7 +4199,7 @@ func (x *Info_Index_UUID_Uncommitted) String() string { func (*Info_Index_UUID_Uncommitted) ProtoMessage() {} func (x *Info_Index_UUID_Uncommitted) ProtoReflect() protoreflect.Message { - mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[68] + mi := &file_apis_proto_v1_payload_payload_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4313,7 +4470,7 @@ var file_apis_proto_v1_payload_payload_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x9a, 0x09, 0x0a, 0x06, 0x4f, 0x62, 0x6a, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xa8, 0x0a, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x75, 0x0a, 0x0d, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, @@ -4387,87 +4544,96 @@ var file_apis_proto_v1_payload_payload_proto_rawDesc = []byte{ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x45, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x1a, 0x3a, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, - 0x28, 0x00, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x66, 0x0a, 0x0a, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x72, 0x1a, 0x58, 0x0a, 0x07, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x6f, 0x64, 0x65, 0x22, 0xe0, 0x07, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0xca, 0x01, - 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x75, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x75, - 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x61, 0x76, 0x69, 0x6e, 0x67, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x1a, 0x4a, - 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x1a, 0x1f, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x1a, 0x21, 0x0a, 0x0b, 0x55, 0x6e, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x1a, 0xef, 0x01, 0x0a, 0x03, 0x50, - 0x6f, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x17, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x72, 0x02, 0x78, 0x01, 0x52, 0x02, 0x69, 0x70, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, - 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x66, 0x6f, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x12, 0x29, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, - 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x1a, 0xe8, 0x01, 0x0a, - 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x12, 0x23, - 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x66, 0x6f, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x2f, 0x0a, 0x06, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x65, - 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x04, - 0x50, 0x6f, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x6f, 0x64, - 0x73, 0x52, 0x04, 0x50, 0x6f, 0x64, 0x73, 0x1a, 0x4b, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x12, 0x14, - 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x75, - 0x73, 0x61, 0x67, 0x65, 0x1a, 0x4e, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x75, - 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x0a, 0x04, 0x50, 0x6f, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x04, - 0x70, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x6f, 0x64, - 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x04, 0x70, 0x6f, 0x64, 0x73, - 0x1a, 0x3e, 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x6e, 0x6f, 0x64, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x42, - 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, - 0x1a, 0x15, 0x0a, 0x03, 0x49, 0x50, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x42, 0x5a, 0x0a, 0x1d, 0x6f, 0x72, 0x67, 0x2e, 0x76, 0x64, 0x61, 0x61, 0x73, 0x2e, 0x76, 0x61, - 0x6c, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x42, 0x0b, 0x56, 0x61, 0x6c, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x01, - 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x64, 0x61, - 0x61, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x8b, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0x09, + 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x78, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, + 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x48, 0x00, 0x52, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0x45, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x1a, 0x3a, + 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x28, 0x00, + 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x66, 0x0a, 0x0a, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x72, 0x1a, 0x58, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x22, 0xe0, 0x07, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0xca, 0x01, 0x0a, 0x05, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x75, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x75, 0x6e, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x1a, 0x4a, 0x0a, 0x04, + 0x55, 0x55, 0x49, 0x44, 0x1a, 0x1f, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x1a, 0x21, 0x0a, 0x0b, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x1a, 0xef, 0x01, 0x0a, 0x03, 0x50, 0x6f, 0x64, + 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x17, 0x0a, + 0x02, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, + 0x78, 0x01, 0x52, 0x02, 0x69, 0x70, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x2f, + 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, + 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, + 0x29, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x04, 0x4e, + 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, + 0x72, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, + 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x04, 0x50, 0x6f, + 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x6f, 0x64, 0x73, 0x52, + 0x04, 0x50, 0x6f, 0x64, 0x73, 0x1a, 0x4b, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x75, 0x73, 0x61, + 0x67, 0x65, 0x1a, 0x4e, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x75, 0x73, 0x61, + 0x67, 0x65, 0x1a, 0x3a, 0x0a, 0x04, 0x50, 0x6f, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x04, 0x70, 0x6f, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x6f, 0x64, 0x42, 0x08, + 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x1a, 0x3e, + 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x1a, 0x15, + 0x0a, 0x03, 0x49, 0x50, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x70, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x5a, + 0x0a, 0x1d, 0x6f, 0x72, 0x67, 0x2e, 0x76, 0x64, 0x61, 0x61, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x64, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, + 0x0b, 0x56, 0x61, 0x6c, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x01, 0x5a, 0x2a, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x64, 0x61, 0x61, 0x73, + 0x2f, 0x76, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, + 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -4483,7 +4649,7 @@ func file_apis_proto_v1_payload_payload_proto_rawDescGZIP() []byte { } var file_apis_proto_v1_payload_payload_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_apis_proto_v1_payload_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 69) +var file_apis_proto_v1_payload_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 72) var file_apis_proto_v1_payload_payload_proto_goTypes = []interface{}{ (Search_AggregationAlgorithm)(0), // 0: payload.v1.Search.AggregationAlgorithm (*Search)(nil), // 1: payload.v1.Search @@ -4541,21 +4707,24 @@ var file_apis_proto_v1_payload_payload_proto_goTypes = []interface{}{ (*Object_Location)(nil), // 53: payload.v1.Object.Location (*Object_StreamLocation)(nil), // 54: payload.v1.Object.StreamLocation (*Object_Locations)(nil), // 55: payload.v1.Object.Locations - (*Control_CreateIndexRequest)(nil), // 56: payload.v1.Control.CreateIndexRequest - (*Discoverer_Request)(nil), // 57: payload.v1.Discoverer.Request - (*Info_Index)(nil), // 58: payload.v1.Info.Index - (*Info_Pod)(nil), // 59: payload.v1.Info.Pod - (*Info_Node)(nil), // 60: payload.v1.Info.Node - (*Info_CPU)(nil), // 61: payload.v1.Info.CPU - (*Info_Memory)(nil), // 62: payload.v1.Info.Memory - (*Info_Pods)(nil), // 63: payload.v1.Info.Pods - (*Info_Nodes)(nil), // 64: payload.v1.Info.Nodes - (*Info_IPs)(nil), // 65: payload.v1.Info.IPs - (*Info_Index_Count)(nil), // 66: payload.v1.Info.Index.Count - (*Info_Index_UUID)(nil), // 67: payload.v1.Info.Index.UUID - (*Info_Index_UUID_Committed)(nil), // 68: payload.v1.Info.Index.UUID.Committed - (*Info_Index_UUID_Uncommitted)(nil), // 69: payload.v1.Info.Index.UUID.Uncommitted - (*status.Status)(nil), // 70: google.rpc.Status + (*Object_List)(nil), // 56: payload.v1.Object.List + (*Object_List_Request)(nil), // 57: payload.v1.Object.List.Request + (*Object_List_Response)(nil), // 58: payload.v1.Object.List.Response + (*Control_CreateIndexRequest)(nil), // 59: payload.v1.Control.CreateIndexRequest + (*Discoverer_Request)(nil), // 60: payload.v1.Discoverer.Request + (*Info_Index)(nil), // 61: payload.v1.Info.Index + (*Info_Pod)(nil), // 62: payload.v1.Info.Pod + (*Info_Node)(nil), // 63: payload.v1.Info.Node + (*Info_CPU)(nil), // 64: payload.v1.Info.CPU + (*Info_Memory)(nil), // 65: payload.v1.Info.Memory + (*Info_Pods)(nil), // 66: payload.v1.Info.Pods + (*Info_Nodes)(nil), // 67: payload.v1.Info.Nodes + (*Info_IPs)(nil), // 68: payload.v1.Info.IPs + (*Info_Index_Count)(nil), // 69: payload.v1.Info.Index.Count + (*Info_Index_UUID)(nil), // 70: payload.v1.Info.Index.UUID + (*Info_Index_UUID_Committed)(nil), // 71: payload.v1.Info.Index.UUID.Committed + (*Info_Index_UUID_Uncommitted)(nil), // 72: payload.v1.Info.Index.UUID.Uncommitted + (*status.Status)(nil), // 73: google.rpc.Status } var file_apis_proto_v1_payload_payload_proto_depIdxs = []int32{ 18, // 0: payload.v1.Search.Request.config:type_name -> payload.v1.Search.Config @@ -4571,7 +4740,7 @@ var file_apis_proto_v1_payload_payload_proto_depIdxs = []int32{ 43, // 10: payload.v1.Search.Response.results:type_name -> payload.v1.Object.Distance 19, // 11: payload.v1.Search.Responses.responses:type_name -> payload.v1.Search.Response 19, // 12: payload.v1.Search.StreamResponse.response:type_name -> payload.v1.Search.Response - 70, // 13: payload.v1.Search.StreamResponse.status:type_name -> google.rpc.Status + 73, // 13: payload.v1.Search.StreamResponse.status:type_name -> google.rpc.Status 22, // 14: payload.v1.Filter.Config.targets:type_name -> payload.v1.Filter.Target 47, // 15: payload.v1.Insert.Request.vector:type_name -> payload.v1.Object.Vector 28, // 16: payload.v1.Insert.Request.config:type_name -> payload.v1.Insert.Config @@ -4603,28 +4772,30 @@ var file_apis_proto_v1_payload_payload_proto_depIdxs = []int32{ 45, // 42: payload.v1.Object.VectorRequest.id:type_name -> payload.v1.Object.ID 23, // 43: payload.v1.Object.VectorRequest.filters:type_name -> payload.v1.Filter.Config 43, // 44: payload.v1.Object.StreamDistance.distance:type_name -> payload.v1.Object.Distance - 70, // 45: payload.v1.Object.StreamDistance.status:type_name -> google.rpc.Status + 73, // 45: payload.v1.Object.StreamDistance.status:type_name -> google.rpc.Status 47, // 46: payload.v1.Object.Vectors.vectors:type_name -> payload.v1.Object.Vector 47, // 47: payload.v1.Object.StreamVector.vector:type_name -> payload.v1.Object.Vector - 70, // 48: payload.v1.Object.StreamVector.status:type_name -> google.rpc.Status + 73, // 48: payload.v1.Object.StreamVector.status:type_name -> google.rpc.Status 51, // 49: payload.v1.Object.StreamBlob.blob:type_name -> payload.v1.Object.Blob - 70, // 50: payload.v1.Object.StreamBlob.status:type_name -> google.rpc.Status + 73, // 50: payload.v1.Object.StreamBlob.status:type_name -> google.rpc.Status 53, // 51: payload.v1.Object.StreamLocation.location:type_name -> payload.v1.Object.Location - 70, // 52: payload.v1.Object.StreamLocation.status:type_name -> google.rpc.Status + 73, // 52: payload.v1.Object.StreamLocation.status:type_name -> google.rpc.Status 53, // 53: payload.v1.Object.Locations.locations:type_name -> payload.v1.Object.Location - 61, // 54: payload.v1.Info.Pod.cpu:type_name -> payload.v1.Info.CPU - 62, // 55: payload.v1.Info.Pod.memory:type_name -> payload.v1.Info.Memory - 60, // 56: payload.v1.Info.Pod.node:type_name -> payload.v1.Info.Node - 61, // 57: payload.v1.Info.Node.cpu:type_name -> payload.v1.Info.CPU - 62, // 58: payload.v1.Info.Node.memory:type_name -> payload.v1.Info.Memory - 63, // 59: payload.v1.Info.Node.Pods:type_name -> payload.v1.Info.Pods - 59, // 60: payload.v1.Info.Pods.pods:type_name -> payload.v1.Info.Pod - 60, // 61: payload.v1.Info.Nodes.nodes:type_name -> payload.v1.Info.Node - 62, // [62:62] is the sub-list for method output_type - 62, // [62:62] is the sub-list for method input_type - 62, // [62:62] is the sub-list for extension type_name - 62, // [62:62] is the sub-list for extension extendee - 0, // [0:62] is the sub-list for field type_name + 47, // 54: payload.v1.Object.List.Response.vector:type_name -> payload.v1.Object.Vector + 73, // 55: payload.v1.Object.List.Response.status:type_name -> google.rpc.Status + 64, // 56: payload.v1.Info.Pod.cpu:type_name -> payload.v1.Info.CPU + 65, // 57: payload.v1.Info.Pod.memory:type_name -> payload.v1.Info.Memory + 63, // 58: payload.v1.Info.Pod.node:type_name -> payload.v1.Info.Node + 64, // 59: payload.v1.Info.Node.cpu:type_name -> payload.v1.Info.CPU + 65, // 60: payload.v1.Info.Node.memory:type_name -> payload.v1.Info.Memory + 66, // 61: payload.v1.Info.Node.Pods:type_name -> payload.v1.Info.Pods + 62, // 62: payload.v1.Info.Pods.pods:type_name -> payload.v1.Info.Pod + 63, // 63: payload.v1.Info.Nodes.nodes:type_name -> payload.v1.Info.Node + 64, // [64:64] is the sub-list for method output_type + 64, // [64:64] is the sub-list for method input_type + 64, // [64:64] is the sub-list for extension type_name + 64, // [64:64] is the sub-list for extension extendee + 0, // [0:64] is the sub-list for field type_name } func init() { file_apis_proto_v1_payload_payload_proto_init() } @@ -5294,7 +5465,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Control_CreateIndexRequest); i { + switch v := v.(*Object_List); i { case 0: return &v.state case 1: @@ -5306,7 +5477,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Discoverer_Request); i { + switch v := v.(*Object_List_Request); i { case 0: return &v.state case 1: @@ -5318,7 +5489,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Index); i { + switch v := v.(*Object_List_Response); i { case 0: return &v.state case 1: @@ -5330,7 +5501,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Pod); i { + switch v := v.(*Control_CreateIndexRequest); i { case 0: return &v.state case 1: @@ -5342,7 +5513,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Node); i { + switch v := v.(*Discoverer_Request); i { case 0: return &v.state case 1: @@ -5354,7 +5525,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_CPU); i { + switch v := v.(*Info_Index); i { case 0: return &v.state case 1: @@ -5366,7 +5537,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Memory); i { + switch v := v.(*Info_Pod); i { case 0: return &v.state case 1: @@ -5378,7 +5549,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Pods); i { + switch v := v.(*Info_Node); i { case 0: return &v.state case 1: @@ -5390,7 +5561,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Nodes); i { + switch v := v.(*Info_CPU); i { case 0: return &v.state case 1: @@ -5402,7 +5573,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_IPs); i { + switch v := v.(*Info_Memory); i { case 0: return &v.state case 1: @@ -5414,7 +5585,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Index_Count); i { + switch v := v.(*Info_Pods); i { case 0: return &v.state case 1: @@ -5426,7 +5597,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Index_UUID); i { + switch v := v.(*Info_Nodes); i { case 0: return &v.state case 1: @@ -5438,7 +5609,7 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info_Index_UUID_Committed); i { + switch v := v.(*Info_IPs); i { case 0: return &v.state case 1: @@ -5450,6 +5621,42 @@ func file_apis_proto_v1_payload_payload_proto_init() { } } file_apis_proto_v1_payload_payload_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Info_Index_Count); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_apis_proto_v1_payload_payload_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Info_Index_UUID); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_apis_proto_v1_payload_payload_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Info_Index_UUID_Committed); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_apis_proto_v1_payload_payload_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Info_Index_UUID_Uncommitted); i { case 0: return &v.state @@ -5482,13 +5689,17 @@ func file_apis_proto_v1_payload_payload_proto_init() { (*Object_StreamLocation_Location)(nil), (*Object_StreamLocation_Status)(nil), } + file_apis_proto_v1_payload_payload_proto_msgTypes[57].OneofWrappers = []interface{}{ + (*Object_List_Response_Vector)(nil), + (*Object_List_Response_Status)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_apis_proto_v1_payload_payload_proto_rawDesc, NumEnums: 1, - NumMessages: 69, + NumMessages: 72, NumExtensions: 0, NumServices: 0, }, diff --git a/apis/grpc/v1/payload/payload_vtproto.pb.go b/apis/grpc/v1/payload/payload_vtproto.pb.go index ac22ec9fba..b0f8162a93 100644 --- a/apis/grpc/v1/payload/payload_vtproto.pb.go +++ b/apis/grpc/v1/payload/payload_vtproto.pb.go @@ -1210,6 +1210,84 @@ func (m *Object_Locations) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *Object_List_Request) CloneVT() *Object_List_Request { + if m == nil { + return (*Object_List_Request)(nil) + } + r := &Object_List_Request{} + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *Object_List_Request) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *Object_List_Response) CloneVT() *Object_List_Response { + if m == nil { + return (*Object_List_Response)(nil) + } + r := &Object_List_Response{} + if m.Payload != nil { + r.Payload = m.Payload.(interface { + CloneVT() isObject_List_Response_Payload + }).CloneVT() + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *Object_List_Response) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *Object_List_Response_Vector) CloneVT() isObject_List_Response_Payload { + if m == nil { + return (*Object_List_Response_Vector)(nil) + } + r := &Object_List_Response_Vector{ + Vector: m.Vector.CloneVT(), + } + return r +} + +func (m *Object_List_Response_Status) CloneVT() isObject_List_Response_Payload { + if m == nil { + return (*Object_List_Response_Status)(nil) + } + r := &Object_List_Response_Status{} + if rhs := m.Status; rhs != nil { + if vtpb, ok := interface{}(rhs).(interface{ CloneVT() *status.Status }); ok { + r.Status = vtpb.CloneVT() + } else { + r.Status = proto.Clone(rhs).(*status.Status) + } + } + return r +} + +func (m *Object_List) CloneVT() *Object_List { + if m == nil { + return (*Object_List)(nil) + } + r := &Object_List{} + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *Object_List) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *Object) CloneVT() *Object { if m == nil { return (*Object)(nil) @@ -3181,6 +3259,120 @@ func (this *Object_Locations) EqualMessageVT(thatMsg proto.Message) bool { } return this.EqualVT(that) } +func (this *Object_List_Request) EqualVT(that *Object_List_Request) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *Object_List_Request) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*Object_List_Request) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *Object_List_Response) EqualVT(that *Object_List_Response) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.Payload == nil && that.Payload != nil { + return false + } else if this.Payload != nil { + if that.Payload == nil { + return false + } + if !this.Payload.(interface { + EqualVT(isObject_List_Response_Payload) bool + }).EqualVT(that.Payload) { + return false + } + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *Object_List_Response) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*Object_List_Response) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *Object_List_Response_Vector) EqualVT(thatIface isObject_List_Response_Payload) bool { + that, ok := thatIface.(*Object_List_Response_Vector) + if !ok { + return false + } + if this == that { + return true + } + if this == nil && that != nil || this != nil && that == nil { + return false + } + if p, q := this.Vector, that.Vector; p != q { + if p == nil { + p = &Object_Vector{} + } + if q == nil { + q = &Object_Vector{} + } + if !p.EqualVT(q) { + return false + } + } + return true +} + +func (this *Object_List_Response_Status) EqualVT(thatIface isObject_List_Response_Payload) bool { + that, ok := thatIface.(*Object_List_Response_Status) + if !ok { + return false + } + if this == that { + return true + } + if this == nil && that != nil || this != nil && that == nil { + return false + } + if p, q := this.Status, that.Status; p != q { + if p == nil { + p = &status.Status{} + } + if q == nil { + q = &status.Status{} + } + if equal, ok := interface{}(p).(interface{ EqualVT(*status.Status) bool }); ok { + if !equal.EqualVT(q) { + return false + } + } else if !proto.Equal(p, q) { + return false + } + } + return true +} + +func (this *Object_List) EqualVT(that *Object_List) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *Object_List) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*Object_List) + if !ok { + return false + } + return this.EqualVT(that) +} func (this *Object) EqualVT(that *Object) bool { if this == that { return true @@ -6298,6 +6490,164 @@ func (m *Object_Locations) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Object_List_Request) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Object_List_Request) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Object_List_Request) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *Object_List_Response) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Object_List_Response) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Object_List_Response) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if vtmsg, ok := m.Payload.(interface { + MarshalToSizedBufferVT([]byte) (int, error) + }); ok { + size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + } + return len(dAtA) - i, nil +} + +func (m *Object_List_Response_Vector) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Object_List_Response_Vector) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Vector != nil { + size, err := m.Vector.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *Object_List_Response_Status) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Object_List_Response_Status) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Status != nil { + if vtmsg, ok := interface{}(m.Status).(interface { + MarshalToSizedBufferVT([]byte) (int, error) + }); ok { + size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } else { + encoded, err := proto.Marshal(m.Status) + if err != nil { + return 0, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = encodeVarint(dAtA, i, uint64(len(encoded))) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *Object_List) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Object_List) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Object_List) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + func (m *Object) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -8126,7 +8476,76 @@ func (m *Object_Location) SizeVT() (n int) { return n } -func (m *Object_StreamLocation) SizeVT() (n int) { +func (m *Object_StreamLocation) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if vtmsg, ok := m.Payload.(interface{ SizeVT() int }); ok { + n += vtmsg.SizeVT() + } + n += len(m.unknownFields) + return n +} + +func (m *Object_StreamLocation_Location) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Location != nil { + l = m.Location.SizeVT() + n += 1 + l + sov(uint64(l)) + } + return n +} +func (m *Object_StreamLocation_Status) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Status != nil { + if size, ok := interface{}(m.Status).(interface { + SizeVT() int + }); ok { + l = size.SizeVT() + } else { + l = proto.Size(m.Status) + } + n += 1 + l + sov(uint64(l)) + } + return n +} +func (m *Object_Locations) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Locations) > 0 { + for _, e := range m.Locations { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *Object_List_Request) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *Object_List_Response) SizeVT() (n int) { if m == nil { return 0 } @@ -8139,19 +8558,19 @@ func (m *Object_StreamLocation) SizeVT() (n int) { return n } -func (m *Object_StreamLocation_Location) SizeVT() (n int) { +func (m *Object_List_Response_Vector) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.Location != nil { - l = m.Location.SizeVT() + if m.Vector != nil { + l = m.Vector.SizeVT() n += 1 + l + sov(uint64(l)) } return n } -func (m *Object_StreamLocation_Status) SizeVT() (n int) { +func (m *Object_List_Response_Status) SizeVT() (n int) { if m == nil { return 0 } @@ -8169,18 +8588,12 @@ func (m *Object_StreamLocation_Status) SizeVT() (n int) { } return n } -func (m *Object_Locations) SizeVT() (n int) { +func (m *Object_List) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Locations) > 0 { - for _, e := range m.Locations { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } n += len(m.unknownFields) return n } @@ -14075,6 +14488,257 @@ func (m *Object_Locations) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *Object_List_Request) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Object_List_Request: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Object_List_Request: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Object_List_Response) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Object_List_Response: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Object_List_Response: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Vector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Payload.(*Object_List_Response_Vector); ok { + if err := oneof.Vector.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &Object_Vector{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Payload = &Object_List_Response_Vector{Vector: v} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Payload.(*Object_List_Response_Status); ok { + if unmarshal, ok := interface{}(oneof.Status).(interface { + UnmarshalVT([]byte) error + }); ok { + if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + if err := proto.Unmarshal(dAtA[iNdEx:postIndex], oneof.Status); err != nil { + return err + } + } + } else { + v := &status.Status{} + if unmarshal, ok := interface{}(v).(interface { + UnmarshalVT([]byte) error + }); ok { + if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + if err := proto.Unmarshal(dAtA[iNdEx:postIndex], v); err != nil { + return err + } + } + m.Payload = &Object_List_Response_Status{Status: v} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Object_List) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Object_List: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Object_List: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Object) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/apis/grpc/v1/vald/object.pb.go b/apis/grpc/v1/vald/object.pb.go index 6c992f0345..c428c3dc53 100644 --- a/apis/grpc/v1/vald/object.pb.go +++ b/apis/grpc/v1/vald/object.pb.go @@ -49,8 +49,8 @@ var file_apis_proto_v1_vald_object_proto_rawDesc = []byte{ 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x95, - 0x02, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x4c, 0x0a, 0x06, 0x45, 0x78, 0x69, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x84, + 0x03, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x4c, 0x0a, 0x06, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x49, 0x44, 0x1a, 0x15, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x49, @@ -67,30 +67,41 @@ var file_apis_proto_v1_vald_object_proto_rawDesc = []byte{ 0x74, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x53, 0x0a, 0x1a, 0x6f, 0x72, 0x67, 0x2e, 0x76, 0x64, - 0x61, 0x61, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x76, 0x61, 0x6c, 0x64, 0x42, 0x0a, 0x56, 0x61, 0x6c, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, - 0x64, 0x61, 0x61, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, - 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6d, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x2e, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x6c, + 0x69, 0x73, 0x74, 0x30, 0x01, 0x42, 0x53, 0x0a, 0x1a, 0x6f, 0x72, 0x67, 0x2e, 0x76, 0x64, 0x61, + 0x61, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x76, + 0x61, 0x6c, 0x64, 0x42, 0x0a, 0x56, 0x61, 0x6c, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, + 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x64, + 0x61, 0x61, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x72, + 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var file_apis_proto_v1_vald_object_proto_goTypes = []interface{}{ (*payload.Object_ID)(nil), // 0: payload.v1.Object.ID (*payload.Object_VectorRequest)(nil), // 1: payload.v1.Object.VectorRequest - (*payload.Object_Vector)(nil), // 2: payload.v1.Object.Vector - (*payload.Object_StreamVector)(nil), // 3: payload.v1.Object.StreamVector + (*payload.Object_List_Request)(nil), // 2: payload.v1.Object.List.Request + (*payload.Object_Vector)(nil), // 3: payload.v1.Object.Vector + (*payload.Object_StreamVector)(nil), // 4: payload.v1.Object.StreamVector + (*payload.Object_List_Response)(nil), // 5: payload.v1.Object.List.Response } var file_apis_proto_v1_vald_object_proto_depIdxs = []int32{ 0, // 0: vald.v1.Object.Exists:input_type -> payload.v1.Object.ID 1, // 1: vald.v1.Object.GetObject:input_type -> payload.v1.Object.VectorRequest 1, // 2: vald.v1.Object.StreamGetObject:input_type -> payload.v1.Object.VectorRequest - 0, // 3: vald.v1.Object.Exists:output_type -> payload.v1.Object.ID - 2, // 4: vald.v1.Object.GetObject:output_type -> payload.v1.Object.Vector - 3, // 5: vald.v1.Object.StreamGetObject:output_type -> payload.v1.Object.StreamVector - 3, // [3:6] is the sub-list for method output_type - 0, // [0:3] is the sub-list for method input_type + 2, // 3: vald.v1.Object.StreamListObject:input_type -> payload.v1.Object.List.Request + 0, // 4: vald.v1.Object.Exists:output_type -> payload.v1.Object.ID + 3, // 5: vald.v1.Object.GetObject:output_type -> payload.v1.Object.Vector + 4, // 6: vald.v1.Object.StreamGetObject:output_type -> payload.v1.Object.StreamVector + 5, // 7: vald.v1.Object.StreamListObject:output_type -> payload.v1.Object.List.Response + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/apis/grpc/v1/vald/object_vtproto.pb.go b/apis/grpc/v1/vald/object_vtproto.pb.go index 73e5f067f3..d1db823e27 100644 --- a/apis/grpc/v1/vald/object_vtproto.pb.go +++ b/apis/grpc/v1/vald/object_vtproto.pb.go @@ -48,6 +48,8 @@ type ObjectClient interface { GetObject(ctx context.Context, in *payload.Object_VectorRequest, opts ...grpc.CallOption) (*payload.Object_Vector, error) // A method to fetch vectors by bidirectional streaming. StreamGetObject(ctx context.Context, opts ...grpc.CallOption) (Object_StreamGetObjectClient, error) + // A method to get all the vectors with server streaming + StreamListObject(ctx context.Context, in *payload.Object_List_Request, opts ...grpc.CallOption) (Object_StreamListObjectClient, error) } type objectClient struct { @@ -107,6 +109,38 @@ func (x *objectStreamGetObjectClient) Recv() (*payload.Object_StreamVector, erro return m, nil } +func (c *objectClient) StreamListObject(ctx context.Context, in *payload.Object_List_Request, opts ...grpc.CallOption) (Object_StreamListObjectClient, error) { + stream, err := c.cc.NewStream(ctx, &Object_ServiceDesc.Streams[1], "/vald.v1.Object/StreamListObject", opts...) + if err != nil { + return nil, err + } + x := &objectStreamListObjectClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Object_StreamListObjectClient interface { + Recv() (*payload.Object_List_Response, error) + grpc.ClientStream +} + +type objectStreamListObjectClient struct { + grpc.ClientStream +} + +func (x *objectStreamListObjectClient) Recv() (*payload.Object_List_Response, error) { + m := new(payload.Object_List_Response) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // ObjectServer is the server API for Object service. // All implementations must embed UnimplementedObjectServer // for forward compatibility @@ -117,6 +151,8 @@ type ObjectServer interface { GetObject(context.Context, *payload.Object_VectorRequest) (*payload.Object_Vector, error) // A method to fetch vectors by bidirectional streaming. StreamGetObject(Object_StreamGetObjectServer) error + // A method to get all the vectors with server streaming + StreamListObject(*payload.Object_List_Request, Object_StreamListObjectServer) error mustEmbedUnimplementedObjectServer() } @@ -133,6 +169,9 @@ func (UnimplementedObjectServer) GetObject(context.Context, *payload.Object_Vect func (UnimplementedObjectServer) StreamGetObject(Object_StreamGetObjectServer) error { return status.Errorf(codes.Unimplemented, "method StreamGetObject not implemented") } +func (UnimplementedObjectServer) StreamListObject(*payload.Object_List_Request, Object_StreamListObjectServer) error { + return status.Errorf(codes.Unimplemented, "method StreamListObject not implemented") +} func (UnimplementedObjectServer) mustEmbedUnimplementedObjectServer() {} // UnsafeObjectServer may be embedded to opt out of forward compatibility for this service. @@ -208,6 +247,27 @@ func (x *objectStreamGetObjectServer) Recv() (*payload.Object_VectorRequest, err return m, nil } +func _Object_StreamListObject_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(payload.Object_List_Request) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ObjectServer).StreamListObject(m, &objectStreamListObjectServer{stream}) +} + +type Object_StreamListObjectServer interface { + Send(*payload.Object_List_Response) error + grpc.ServerStream +} + +type objectStreamListObjectServer struct { + grpc.ServerStream +} + +func (x *objectStreamListObjectServer) Send(m *payload.Object_List_Response) error { + return x.ServerStream.SendMsg(m) +} + // Object_ServiceDesc is the grpc.ServiceDesc for Object service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -231,6 +291,11 @@ var Object_ServiceDesc = grpc.ServiceDesc{ ServerStreams: true, ClientStreams: true, }, + { + StreamName: "StreamListObject", + Handler: _Object_StreamListObject_Handler, + ServerStreams: true, + }, }, Metadata: "apis/proto/v1/vald/object.proto", } diff --git a/apis/grpc/v1/vald/vald.go b/apis/grpc/v1/vald/vald.go index 01c12f8666..ff343ec61b 100644 --- a/apis/grpc/v1/vald/vald.go +++ b/apis/grpc/v1/vald/vald.go @@ -120,9 +120,10 @@ const ( StreamRemoveRPCName = "StreamRemove" MultiRemoveRPCName = "MultiRemove" - ExistsRPCName = "Exists" - GetObjectRPCName = "GetObject" - StreamGetObjectRPCName = "StreamGetObject" + ExistsRPCName = "Exists" + GetObjectRPCName = "GetObject" + StreamGetObjectRPCName = "StreamGetObject" + StreamListObjectRPCName = "StreamListObject" ) type client struct { diff --git a/apis/proto/v1/payload/payload.proto b/apis/proto/v1/payload/payload.proto index 574503f853..4a6f4edc5f 100644 --- a/apis/proto/v1/payload/payload.proto +++ b/apis/proto/v1/payload/payload.proto @@ -418,6 +418,17 @@ message Object { message Locations { repeated Location locations = 1; } + + message List { + message Request {} + + message Response { + oneof payload { + Vector vector = 1; + google.rpc.Status status = 2; + } + } + } } // Control related messages. diff --git a/apis/proto/v1/vald/object.proto b/apis/proto/v1/vald/object.proto index f275e29096..8bb6e6c54c 100644 --- a/apis/proto/v1/vald/object.proto +++ b/apis/proto/v1/vald/object.proto @@ -40,4 +40,9 @@ service Object { // A method to fetch vectors by bidirectional streaming. rpc StreamGetObject(stream payload.v1.Object.VectorRequest) returns (stream payload.v1.Object.StreamVector) {} + + // A method to get all the vectors with server streaming + rpc StreamListObject(payload.v1.Object.List.Request) returns (stream payload.v1.Object.List.Response) { + option (google.api.http).get = "/object/list"; + } } diff --git a/apis/swagger/v1/vald/apis/proto/v1/vald/filter.swagger.json b/apis/swagger/v1/vald/apis/proto/v1/vald/filter.swagger.json index d98f15559e..0e52e2800e 100644 --- a/apis/swagger/v1/vald/apis/proto/v1/vald/filter.swagger.json +++ b/apis/swagger/v1/vald/apis/proto/v1/vald/filter.swagger.json @@ -77,7 +77,7 @@ "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" } }, "default": { @@ -340,30 +340,13 @@ "default": "Unknown", "title": "AggregationAlgorithm is enum of each aggregation algorithms" }, - "SearchResponse": { - "type": "object", - "properties": { - "requestId": { - "type": "string", - "description": "The unique request ID." - }, - "results": { - "type": "array", - "items": { - "$ref": "#/definitions/ObjectDistance" - }, - "description": "Search results." - } - }, - "description": "Represent a search response." - }, "SearchResponses": { "type": "object", "properties": { "responses": { "type": "array", "items": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" }, "description": "Represent the multiple search response content." } @@ -374,7 +357,7 @@ "type": "object", "properties": { "response": { - "$ref": "#/definitions/SearchResponse", + "$ref": "#/definitions/v1SearchResponse", "description": "Represent the search response." }, "status": { @@ -630,6 +613,23 @@ }, "description": "Represent a search by binary object request." }, + "v1SearchResponse": { + "type": "object", + "properties": { + "requestId": { + "type": "string", + "description": "The unique request ID." + }, + "results": { + "type": "array", + "items": { + "$ref": "#/definitions/ObjectDistance" + }, + "description": "Search results." + } + }, + "description": "Represent a search response." + }, "v1UpdateConfig": { "type": "object", "properties": { diff --git a/apis/swagger/v1/vald/apis/proto/v1/vald/object.swagger.json b/apis/swagger/v1/vald/apis/proto/v1/vald/object.swagger.json index da1aa1cd14..36dd578ab7 100644 --- a/apis/swagger/v1/vald/apis/proto/v1/vald/object.swagger.json +++ b/apis/swagger/v1/vald/apis/proto/v1/vald/object.swagger.json @@ -36,6 +36,36 @@ "tags": ["Object"] } }, + "/object/list": { + "get": { + "summary": "A method to get all the vectors with server streaming", + "operationId": "Object_StreamListObject", + "responses": { + "200": { + "description": "A successful response.(streaming responses)", + "schema": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/ObjectListResponse" + }, + "error": { + "$ref": "#/definitions/runtimeStreamError" + } + }, + "title": "Stream result of ObjectListResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + }, + "tags": ["Object"] + } + }, "/object/{id.id}": { "get": { "summary": "A method to fetch a vector.", @@ -91,6 +121,17 @@ }, "description": "Represent the vector ID." }, + "ObjectListResponse": { + "type": "object", + "properties": { + "vector": { + "$ref": "#/definitions/ObjectVector" + }, + "status": { + "$ref": "#/definitions/rpcStatus" + } + } + }, "ObjectStreamVector": { "type": "object", "properties": { diff --git a/apis/swagger/v1/vald/apis/proto/v1/vald/search.swagger.json b/apis/swagger/v1/vald/apis/proto/v1/vald/search.swagger.json index 4a193c0d84..9965724de9 100644 --- a/apis/swagger/v1/vald/apis/proto/v1/vald/search.swagger.json +++ b/apis/swagger/v1/vald/apis/proto/v1/vald/search.swagger.json @@ -15,7 +15,7 @@ "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" } }, "default": { @@ -46,7 +46,7 @@ "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" } }, "default": { @@ -139,7 +139,7 @@ "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" } }, "default": { @@ -170,7 +170,7 @@ "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" } }, "default": { @@ -326,30 +326,13 @@ }, "description": "Represent the multiple search by ID request." }, - "SearchResponse": { - "type": "object", - "properties": { - "requestId": { - "type": "string", - "description": "The unique request ID." - }, - "results": { - "type": "array", - "items": { - "$ref": "#/definitions/ObjectDistance" - }, - "description": "Search results." - } - }, - "description": "Represent a search response." - }, "SearchResponses": { "type": "object", "properties": { "responses": { "type": "array", "items": { - "$ref": "#/definitions/SearchResponse" + "$ref": "#/definitions/v1SearchResponse" }, "description": "Represent the multiple search response content." } @@ -360,7 +343,7 @@ "type": "object", "properties": { "response": { - "$ref": "#/definitions/SearchResponse", + "$ref": "#/definitions/v1SearchResponse", "description": "Represent the search response." }, "status": { @@ -543,6 +526,23 @@ } }, "description": "Represent a search request." + }, + "v1SearchResponse": { + "type": "object", + "properties": { + "requestId": { + "type": "string", + "description": "The unique request ID." + }, + "results": { + "type": "array", + "items": { + "$ref": "#/definitions/ObjectDistance" + }, + "description": "Search results." + } + }, + "description": "Represent a search response." } } } diff --git a/go.mod b/go.mod index 7aa07867e1..38f9c817bc 100755 --- a/go.mod +++ b/go.mod @@ -480,6 +480,7 @@ require ( github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/xlab/treeprint v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect diff --git a/internal/net/grpc/status/status.go b/internal/net/grpc/status/status.go index 99ab7bcf1a..7220779557 100644 --- a/internal/net/grpc/status/status.go +++ b/internal/net/grpc/status/status.go @@ -110,6 +110,10 @@ func WrapWithUnauthenticated(msg string, err error, details ...interface{}) erro return newStatus(codes.Unauthenticated, msg, err, details...).Err() } +func CreateWithNotFound(msg string, err error, details ...interface{}) *Status { + return newStatus(codes.NotFound, msg, err, details...) +} + func Error(code codes.Code, msg string) error { return status.Error(code, msg) } diff --git a/internal/net/grpc/stream.go b/internal/net/grpc/stream.go index dcafda62bb..3cc32b9bd1 100644 --- a/internal/net/grpc/stream.go +++ b/internal/net/grpc/stream.go @@ -42,12 +42,18 @@ type ( ServerStream = grpc.ServerStream ) -// BidirectionalStream represents gRPC bidirectional stream server handler. +// BidirectionalStream[Q any, R any] represents gRPC bidirectional stream server handler. +// It receives a context, a server stream, a concurrency integer, and a function that takes a context and a pointer to Q and returns a pointer to R and an error. +// It returns an error. +// It receives messages from the stream, calls the function with the received message, and sends the returned message to the stream. +// It limits the number of concurrent calls to the function with the concurrency integer. +// It records errors and returns them as a single error. +// It uses the context to control the lifecycle of the stream. func BidirectionalStream[Q any, R any](ctx context.Context, stream ServerStream, concurrency int, f func(context.Context, *Q) (*R, error), ) (err error) { - ctx, span := trace.StartSpan(stream.Context(), apiName+"/BidirectionalStream") + ctx, span := trace.StartSpan(ctx, apiName+"/BidirectionalStream") defer func() { if span != nil { span.End() diff --git a/internal/net/grpc/stream_test.go b/internal/net/grpc/stream_test.go index bd89cef394..ea37fcabe1 100644 --- a/internal/net/grpc/stream_test.go +++ b/internal/net/grpc/stream_test.go @@ -22,6 +22,8 @@ import ( "reflect" "testing" + tmock "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/vdaas/vald/apis/grpc/v1/payload" "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/io" @@ -29,8 +31,65 @@ import ( "github.com/vdaas/vald/internal/test/data/vector" "github.com/vdaas/vald/internal/test/goleak" "github.com/vdaas/vald/internal/test/mock" + "google.golang.org/grpc/metadata" ) +type MockServerStream struct { + tmock.Mock +} + +func (m *MockServerStream) SendMsg(msg interface{}) error { + args := m.Called(msg) + return args.Error(0) +} + +func (m *MockServerStream) SetHeader(metadata.MD) error { + return nil +} + +func (m *MockServerStream) SendHeader(metadata.MD) error { + return nil +} + +func (m *MockServerStream) SetTrailer(metadata.MD) { +} + +func (m *MockServerStream) Context() context.Context { + return context.Background() +} + +func (m *MockServerStream) SendMsgWithContext(ctx context.Context, msg interface{}) error { + args := m.Called(msg) + return args.Error(0) +} + +func (m *MockServerStream) RecvMsg(msg interface{}) error { + return nil +} + +func TestServerSideStream_Success(t *testing.T) { + // Create a new mock server stream + mockStream := new(MockServerStream) + + // Set expectations for the mock stream + mockStream.On("SendMsg", tmock.AnythingOfType("*string")).Return(nil).Times(3) + + // Define the function to be passed to ServerSideStream + f := func(ctx context.Context, req *string) (*string, error) { + return req, nil + } + + // Call the ServerSideStream function + r := "test" + err := ServerSideStream(context.Background(), &r, mockStream, 3, f) + + // Assert that the function returned no errors + require.NoError(t, err) + + // Assert that the mock stream expectations were met + mockStream.AssertExpectations(t) +} + func TestBidirectionalStream(t *testing.T) { type args struct { concurrency int diff --git a/internal/test/mock/grpc_testify_mock.go b/internal/test/mock/grpc_testify_mock.go new file mode 100644 index 0000000000..70a2951ba9 --- /dev/null +++ b/internal/test/mock/grpc_testify_mock.go @@ -0,0 +1,54 @@ +// Copyright (C) 2019-2023 vdaas.org vald team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package mock + +import ( + "context" + + "github.com/stretchr/testify/mock" + "google.golang.org/grpc/metadata" +) + +// ServerStreamTestifyMock is a testify mock struct for grpc.ServerStream. +// Define Send method on top of this for each specific usecases with your specific proto schema Go struct type. +type ServerStreamTestifyMock struct { + mock.Mock +} + +func (sssm *ServerStreamTestifyMock) SendMsg(msg interface{}) error { + return nil +} + +func (sssm *ServerStreamTestifyMock) SetHeader(metadata.MD) error { + return nil +} + +func (sssm *ServerStreamTestifyMock) SendHeader(metadata.MD) error { + return nil +} + +func (sssm *ServerStreamTestifyMock) SetTrailer(metadata.MD) { +} + +func (sssm *ServerStreamTestifyMock) Context() context.Context { + return context.Background() +} + +func (sssm *ServerStreamTestifyMock) SendMsgWithContext(ctx context.Context, msg interface{}) error { + return nil +} + +func (sssm *ServerStreamTestifyMock) RecvMsg(msg interface{}) error { + return nil +} diff --git a/pkg/agent/core/ngt/handler/grpc/object.go b/pkg/agent/core/ngt/handler/grpc/object.go index e5ec2331e9..9356e36740 100644 --- a/pkg/agent/core/ngt/handler/grpc/object.go +++ b/pkg/agent/core/ngt/handler/grpc/object.go @@ -27,6 +27,7 @@ import ( "github.com/vdaas/vald/internal/net/grpc/errdetails" "github.com/vdaas/vald/internal/net/grpc/status" "github.com/vdaas/vald/internal/observability/trace" + "github.com/vdaas/vald/internal/slices" ) func (s *server) Exists(ctx context.Context, uid *payload.Object_ID) (res *payload.Object_ID, err error) { @@ -198,3 +199,58 @@ func (s *server) StreamGetObject(stream vald.Object_StreamGetObjectServer) (err } return nil } + +func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Object_StreamListObjectServer) (err error) { + ctx, span := trace.StartSpan(stream.Context(), apiName+"/"+vald.StreamListObjectRPCName) + defer func() { + if span != nil { + span.End() + } + }() + + errs := make([]error, 0, s.ngt.Len()) + s.ngt.ListObjectFunc(ctx, func(uuid string, _ uint32, _ int64) bool { + vec, ts, err := s.ngt.GetObject(uuid) + if err != nil { + st := status.CreateWithNotFound(fmt.Sprintf("failed to get object with uuid: %s", uuid), err) + err := stream.Send(&payload.Object_List_Response{ + Payload: &payload.Object_List_Response_Status{ + Status: st.Proto(), + }, + }) + if err != nil { + errs = append(errs, err) + } + return true + } + + err = stream.Send(&payload.Object_List_Response{ + Payload: &payload.Object_List_Response_Vector{ + Vector: &payload.Object_Vector{ + Id: uuid, + Vector: vec, + Timestamp: ts, + }, + }, + }) + if err != nil { + errs = append(errs, err) + } + return true + }) + + if len(errs) != 0 { + slices.RemoveDuplicates(errs, func(left, right error) bool { + return left.Error() < right.Error() + }) + err = errors.Join(errs...) + st, msg, err := status.ParseError(err, codes.Internal, "failed to parse StreamListObject final gRPC error response") + if span != nil { + span.RecordError(err) + span.SetAttributes(trace.FromGRPCStatus(st.Code(), msg)...) + span.SetStatus(trace.StatusError, msg) + } + return err + } + return nil +} diff --git a/pkg/agent/core/ngt/handler/grpc/object_test.go b/pkg/agent/core/ngt/handler/grpc/object_test.go index f44cdb8b18..61225918f0 100644 --- a/pkg/agent/core/ngt/handler/grpc/object_test.go +++ b/pkg/agent/core/ngt/handler/grpc/object_test.go @@ -18,6 +18,8 @@ import ( "reflect" "testing" + tmock "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/vdaas/vald/apis/grpc/v1/payload" "github.com/vdaas/vald/internal/config" "github.com/vdaas/vald/internal/conv" @@ -29,6 +31,8 @@ import ( "github.com/vdaas/vald/internal/net/grpc/status" "github.com/vdaas/vald/internal/test/data/request" "github.com/vdaas/vald/internal/test/data/vector" + "github.com/vdaas/vald/internal/test/goleak" + "github.com/vdaas/vald/internal/test/mock" "github.com/vdaas/vald/pkg/agent/core/ngt/service" ) @@ -133,7 +137,7 @@ func Test_server_Exists(t *testing.T) { - case 3.6: success exists with euc-jp ID from euc-jp index - case 4.1: success exists with 😀 - Decision Table Testing - - NONE + - NONE */ tests := []test{ { @@ -1185,6 +1189,165 @@ func Test_server_GetObject(t *testing.T) { } } +type ListObjectStreamMock struct { + mock.ServerStreamTestifyMock +} + +func (sssm *ListObjectStreamMock) Send(res *payload.Object_List_Response) error { + args := sssm.Called(res) + return args.Error(0) +} + +func Test_server_StreamGetObject(t *testing.T) { + t.Parallel() + + defaultConfig := config.NGT{ + Dimension: 100, + DistanceType: "l2", + ObjectType: "float", + BulkInsertChunkSize: 10, + CreationEdgeSize: 20, + SearchEdgeSize: 10, + EnableProactiveGC: false, + EnableCopyOnWrite: false, + KVSDB: &config.KVSDB{ + Concurrency: 10, + }, + BrokenIndexHistoryLimit: 1, + } + + setup := func(t *testing.T) (context.Context, Server) { + t.Helper() + ngt, err := service.New(&defaultConfig) + require.NoError(t, err) + + ctx := context.Background() + eg, ectx := errgroup.New(ctx) + opts := []Option{ + WithIP(net.LoadLocalIP()), + WithNGT(ngt), + WithErrGroup(eg), + } + s, err := New(opts...) + require.NoError(t, err) + + return ectx, s + } + + type test struct { + name string + testfunc func(t *testing.T) + } + + tests := []test{ + { + name: "returns multiple objects", + testfunc: func(t *testing.T) { + ectx, s := setup(t) + + // insert and create `num` index + num := 42 + req, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, num, 100, &payload.Insert_Config{}) + require.NoError(t, err) + + _, err = s.MultiInsert(ectx, req) + require.NoError(t, err) + + _, err = s.CreateIndex(ectx, &payload.Control_CreateIndexRequest{ + PoolSize: uint32(len(req.Requests)), + }) + require.NoError(t, err) + + // Set mock and expectations + stream := ListObjectStreamMock{} + stream.On("Send", tmock.Anything).Return(nil) + + // Call the method under test + err = s.StreamListObject(&payload.Object_List_Request{}, &stream) + require.NoError(t, err) + + // Check results + stream.AssertExpectations(t) + stream.AssertNumberOfCalls(t, "Send", num) + for _, req := range req.Requests { + stream.AssertCalled(t, "Send", tmock.MatchedBy(func(r *payload.Object_List_Response) bool { + vec := *r.GetVector() + wantVec := req.GetVector() + // Check every fields but timestamp + if vec.GetId() != wantVec.GetId() { + return false + } + if !reflect.DeepEqual(vec.GetVector(), wantVec.GetVector()) { + return false + } + return true + })) + } + }, + }, + { + name: "returns joined error when Send fails in the stream", + testfunc: func(t *testing.T) { + ectx, s := setup(t) + + // insert and create some index + req, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, 2, 100, &payload.Insert_Config{}) + require.NoError(t, err) + + _, err = s.MultiInsert(ectx, req) + require.NoError(t, err) + + _, err = s.CreateIndex(ectx, &payload.Control_CreateIndexRequest{ + PoolSize: uint32(len(req.Requests)), + }) + require.NoError(t, err) + + // Set mock and expectations + stream := ListObjectStreamMock{} + stream.On("Send", tmock.Anything).Return(status.New(codes.Unknown, "foo").Err()).Once() + stream.On("Send", tmock.Anything).Return(status.New(codes.Aborted, "bar").Err()) + + // Call the method under test + err = s.StreamListObject(&payload.Object_List_Request{}, &stream) + + // Check the errros are joined and its a gRPC error + require.ErrorContains(t, err, "foo") + require.ErrorContains(t, err, "bar") + _, ok := status.FromError(err) + require.True(t, ok, "err should be a gRPC error") + + stream.AssertExpectations(t) + }, + }, + { + name: "Send must not be called when there is no index", + testfunc: func(t *testing.T) { + _, s := setup(t) + + // Set mock and expectations + stream := ListObjectStreamMock{} + stream.On("Send", tmock.Anything).Return(nil) + + // Call the method under test + err := s.StreamListObject(&payload.Object_List_Request{}, &stream) + require.NoError(t, err) + + // Check results + stream.AssertNotCalled(t, "Send", tmock.Anything) + }, + }, + } + + for _, tc := range tests { + test := tc + t.Run(test.name, func(tt *testing.T) { + tt.Parallel() + defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) + test.testfunc(tt) + }) + } +} + // NOT IMPLEMENTED BELOW // // func Test_server_StreamGetObject(t *testing.T) { diff --git a/pkg/agent/core/ngt/service/ngt.go b/pkg/agent/core/ngt/service/ngt.go index dc4f54515d..60cbcd589d 100644 --- a/pkg/agent/core/ngt/service/ngt.go +++ b/pkg/agent/core/ngt/service/ngt.go @@ -67,6 +67,7 @@ type NGT interface { DeleteMultiple(uuids ...string) (err error) DeleteMultipleWithTime(uuids []string, t int64) (err error) GetObject(uuid string) (vec []float32, timestamp int64, err error) + ListObjectFunc(ctx context.Context, f func(uuid string, oid uint32, timestamp int64) bool) CreateIndex(ctx context.Context, poolSize uint32) (err error) SaveIndex(ctx context.Context) (err error) Exists(string) (uint32, bool) @@ -1714,3 +1715,9 @@ func (n *ngt) Close(ctx context.Context) (err error) { func (n *ngt) BrokenIndexCount() uint64 { return atomic.LoadUint64(&n.nobic) } + +// ListObjectFunc applies the input function on each index stored in the kvs. +// Use this function for performing something on each object with caring about the memory usage. +func (n *ngt) ListObjectFunc(ctx context.Context, f func(uuid string, oid uint32, ts int64) bool) { + n.kvs.Range(ctx, f) +} From 7436411c53ead26f16ac6fcb95be0a2d758c4027 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Tue, 1 Aug 2023 02:27:05 +0000 Subject: [PATCH 02/10] Add methods to custom gRPC client --- internal/client/v1/client/vald/vald.go | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/internal/client/v1/client/vald/vald.go b/internal/client/v1/client/vald/vald.go index f26aa7a45d..4181102b5b 100644 --- a/internal/client/v1/client/vald/vald.go +++ b/internal/client/v1/client/vald/vald.go @@ -621,6 +621,25 @@ func (c *client) StreamGetObject(ctx context.Context, opts ...grpc.CallOption) ( return res, nil } +func (c *client) StreamListObject(ctx context.Context, in *payload.Object_List_Request, opts ...grpc.CallOption) (res vald.Object_StreamListObjectClient, err error) { + ctx, span := trace.StartSpan(grpc.WrapGRPCMethod(ctx, "internal/client/"+vald.StreamListObjectRPCName), apiName+"/"+vald.StreamListObjectRPCName) + defer func() { + if span != nil { + span.End() + } + }() + _, err = c.c.RoundRobin(ctx, func(ctx context.Context, + conn *grpc.ClientConn, + copts ...grpc.CallOption, + ) (interface{}, error) { + return vald.NewValdClient(conn).StreamListObject(ctx, in, append(copts, opts...)...) + }) + if err != nil { + return nil, err + } + return res, nil +} + func (*singleClient) Start(context.Context) (<-chan error, error) { return nil, nil } @@ -902,3 +921,13 @@ func (c *singleClient) StreamGetObject(ctx context.Context, opts ...grpc.CallOpt }() return c.vc.StreamGetObject(ctx, opts...) } + +func (c *singleClient) StreamListObject(ctx context.Context, in *payload.Object_List_Request, opts ...grpc.CallOption) (res vald.Object_StreamListObjectClient, err error) { + ctx, span := trace.StartSpan(grpc.WrapGRPCMethod(ctx, "internal/singleClient/"+vald.StreamListObjectRPCName), apiName+"/"+vald.StreamListObjectRPCName) + defer func() { + if span != nil { + span.End() + } + }() + return c.vc.StreamListObject(ctx, in, opts...) +} From 1952b5cee931060f2b3b4bcceb970f485e2f7c53 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Tue, 1 Aug 2023 02:41:18 +0000 Subject: [PATCH 03/10] handle data race --- pkg/agent/core/ngt/handler/grpc/object.go | 18 +++++++++++++++++- pkg/agent/core/ngt/handler/grpc/object_test.go | 2 -- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/object.go b/pkg/agent/core/ngt/handler/grpc/object.go index 9356e36740..c2bd134042 100644 --- a/pkg/agent/core/ngt/handler/grpc/object.go +++ b/pkg/agent/core/ngt/handler/grpc/object.go @@ -16,6 +16,7 @@ package grpc import ( "context" "fmt" + "sync" "github.com/vdaas/vald/apis/grpc/v1/payload" "github.com/vdaas/vald/apis/grpc/v1/vald" @@ -208,22 +209,33 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob } }() - errs := make([]error, 0, s.ngt.Len()) + var ( + mu sync.Mutex + emu sync.Mutex + errs = make([]error, 0, s.ngt.Len()) + ) s.ngt.ListObjectFunc(ctx, func(uuid string, _ uint32, _ int64) bool { vec, ts, err := s.ngt.GetObject(uuid) if err != nil { st := status.CreateWithNotFound(fmt.Sprintf("failed to get object with uuid: %s", uuid), err) + + mu.Lock() err := stream.Send(&payload.Object_List_Response{ Payload: &payload.Object_List_Response_Status{ Status: st.Proto(), }, }) + mu.Unlock() + if err != nil { + emu.Lock() errs = append(errs, err) + emu.Unlock() } return true } + mu.Lock() err = stream.Send(&payload.Object_List_Response{ Payload: &payload.Object_List_Response_Vector{ Vector: &payload.Object_Vector{ @@ -233,8 +245,12 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob }, }, }) + mu.Unlock() + if err != nil { + emu.Lock() errs = append(errs, err) + emu.Unlock() } return true }) diff --git a/pkg/agent/core/ngt/handler/grpc/object_test.go b/pkg/agent/core/ngt/handler/grpc/object_test.go index 61225918f0..532ab56d0c 100644 --- a/pkg/agent/core/ngt/handler/grpc/object_test.go +++ b/pkg/agent/core/ngt/handler/grpc/object_test.go @@ -31,7 +31,6 @@ import ( "github.com/vdaas/vald/internal/net/grpc/status" "github.com/vdaas/vald/internal/test/data/request" "github.com/vdaas/vald/internal/test/data/vector" - "github.com/vdaas/vald/internal/test/goleak" "github.com/vdaas/vald/internal/test/mock" "github.com/vdaas/vald/pkg/agent/core/ngt/service" ) @@ -1342,7 +1341,6 @@ func Test_server_StreamGetObject(t *testing.T) { test := tc t.Run(test.name, func(tt *testing.T) { tt.Parallel() - defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) test.testfunc(tt) }) } From 8f64ca761fc382fe968a0d0dfd10482f806dbe74 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Tue, 1 Aug 2023 03:27:49 +0000 Subject: [PATCH 04/10] remove unused test --- internal/net/grpc/stream_test.go | 59 -------------------------------- 1 file changed, 59 deletions(-) diff --git a/internal/net/grpc/stream_test.go b/internal/net/grpc/stream_test.go index ea37fcabe1..bd89cef394 100644 --- a/internal/net/grpc/stream_test.go +++ b/internal/net/grpc/stream_test.go @@ -22,8 +22,6 @@ import ( "reflect" "testing" - tmock "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" "github.com/vdaas/vald/apis/grpc/v1/payload" "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/io" @@ -31,65 +29,8 @@ import ( "github.com/vdaas/vald/internal/test/data/vector" "github.com/vdaas/vald/internal/test/goleak" "github.com/vdaas/vald/internal/test/mock" - "google.golang.org/grpc/metadata" ) -type MockServerStream struct { - tmock.Mock -} - -func (m *MockServerStream) SendMsg(msg interface{}) error { - args := m.Called(msg) - return args.Error(0) -} - -func (m *MockServerStream) SetHeader(metadata.MD) error { - return nil -} - -func (m *MockServerStream) SendHeader(metadata.MD) error { - return nil -} - -func (m *MockServerStream) SetTrailer(metadata.MD) { -} - -func (m *MockServerStream) Context() context.Context { - return context.Background() -} - -func (m *MockServerStream) SendMsgWithContext(ctx context.Context, msg interface{}) error { - args := m.Called(msg) - return args.Error(0) -} - -func (m *MockServerStream) RecvMsg(msg interface{}) error { - return nil -} - -func TestServerSideStream_Success(t *testing.T) { - // Create a new mock server stream - mockStream := new(MockServerStream) - - // Set expectations for the mock stream - mockStream.On("SendMsg", tmock.AnythingOfType("*string")).Return(nil).Times(3) - - // Define the function to be passed to ServerSideStream - f := func(ctx context.Context, req *string) (*string, error) { - return req, nil - } - - // Call the ServerSideStream function - r := "test" - err := ServerSideStream(context.Background(), &r, mockStream, 3, f) - - // Assert that the function returned no errors - require.NoError(t, err) - - // Assert that the mock stream expectations were met - mockStream.AssertExpectations(t) -} - func TestBidirectionalStream(t *testing.T) { type args struct { concurrency int From 17d18bdb6288b8d94c8033dbb25a8315babe5080 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Tue, 1 Aug 2023 04:43:34 +0000 Subject: [PATCH 05/10] fix deepsource error --- internal/net/grpc/stream.go | 5 +---- internal/test/mock/grpc_testify_mock.go | 14 +++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/internal/net/grpc/stream.go b/internal/net/grpc/stream.go index 3cc32b9bd1..72a2ecf320 100644 --- a/internal/net/grpc/stream.go +++ b/internal/net/grpc/stream.go @@ -42,13 +42,10 @@ type ( ServerStream = grpc.ServerStream ) -// BidirectionalStream[Q any, R any] represents gRPC bidirectional stream server handler. -// It receives a context, a server stream, a concurrency integer, and a function that takes a context and a pointer to Q and returns a pointer to R and an error. -// It returns an error. +// BidirectionalStream represents gRPC bidirectional stream server handler. // It receives messages from the stream, calls the function with the received message, and sends the returned message to the stream. // It limits the number of concurrent calls to the function with the concurrency integer. // It records errors and returns them as a single error. -// It uses the context to control the lifecycle of the stream. func BidirectionalStream[Q any, R any](ctx context.Context, stream ServerStream, concurrency int, f func(context.Context, *Q) (*R, error), diff --git a/internal/test/mock/grpc_testify_mock.go b/internal/test/mock/grpc_testify_mock.go index 70a2951ba9..1f9ceb513f 100644 --- a/internal/test/mock/grpc_testify_mock.go +++ b/internal/test/mock/grpc_testify_mock.go @@ -26,29 +26,29 @@ type ServerStreamTestifyMock struct { mock.Mock } -func (sssm *ServerStreamTestifyMock) SendMsg(msg interface{}) error { +func (*ServerStreamTestifyMock) SendMsg(_ interface{}) error { return nil } -func (sssm *ServerStreamTestifyMock) SetHeader(metadata.MD) error { +func (*ServerStreamTestifyMock) SetHeader(metadata.MD) error { return nil } -func (sssm *ServerStreamTestifyMock) SendHeader(metadata.MD) error { +func (*ServerStreamTestifyMock) SendHeader(metadata.MD) error { return nil } -func (sssm *ServerStreamTestifyMock) SetTrailer(metadata.MD) { +func (*ServerStreamTestifyMock) SetTrailer(metadata.MD) { } -func (sssm *ServerStreamTestifyMock) Context() context.Context { +func (*ServerStreamTestifyMock) Context() context.Context { return context.Background() } -func (sssm *ServerStreamTestifyMock) SendMsgWithContext(ctx context.Context, msg interface{}) error { +func (*ServerStreamTestifyMock) SendMsgWithContext(_ context.Context, _ interface{}) error { return nil } -func (sssm *ServerStreamTestifyMock) RecvMsg(msg interface{}) error { +func (*ServerStreamTestifyMock) RecvMsg(_ interface{}) error { return nil } From 49814fd564c464e9620e9247adecc860a4df9bd5 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Tue, 1 Aug 2023 09:18:58 +0000 Subject: [PATCH 06/10] add comment --- apis/proto/v1/payload/payload.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apis/proto/v1/payload/payload.proto b/apis/proto/v1/payload/payload.proto index 4a6f4edc5f..dd0ebef729 100644 --- a/apis/proto/v1/payload/payload.proto +++ b/apis/proto/v1/payload/payload.proto @@ -419,12 +419,15 @@ message Object { repeated Location locations = 1; } + // Represent the list object vector stream request and response. message List { message Request {} message Response { oneof payload { + // The vector Vector vector = 1; + // The RPC error status. google.rpc.Status status = 2; } } From f64b1c4ad2011f614e2cf7b4f1008f3950da13dd Mon Sep 17 00:00:00 2001 From: ykadowak Date: Tue, 1 Aug 2023 09:26:16 +0000 Subject: [PATCH 07/10] move mocks to the mock pkgs --- internal/test/mock/grpc_testify_mock.go | 11 +++++++++++ pkg/agent/core/ngt/handler/grpc/object_test.go | 15 +++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/internal/test/mock/grpc_testify_mock.go b/internal/test/mock/grpc_testify_mock.go index 1f9ceb513f..1a6b5cdde6 100644 --- a/internal/test/mock/grpc_testify_mock.go +++ b/internal/test/mock/grpc_testify_mock.go @@ -17,6 +17,7 @@ import ( "context" "github.com/stretchr/testify/mock" + "github.com/vdaas/vald/apis/grpc/v1/payload" "google.golang.org/grpc/metadata" ) @@ -52,3 +53,13 @@ func (*ServerStreamTestifyMock) SendMsgWithContext(_ context.Context, _ interfac func (*ServerStreamTestifyMock) RecvMsg(_ interface{}) error { return nil } + +// ListObjectStreamMock is a testify mock struct for ListObjectStream based on ServerStreamTestifyMock +type ListObjectStreamMock struct { + ServerStreamTestifyMock +} + +func (losm *ListObjectStreamMock) Send(res *payload.Object_List_Response) error { + args := losm.Called(res) + return args.Error(0) +} diff --git a/pkg/agent/core/ngt/handler/grpc/object_test.go b/pkg/agent/core/ngt/handler/grpc/object_test.go index 532ab56d0c..edd5a044cf 100644 --- a/pkg/agent/core/ngt/handler/grpc/object_test.go +++ b/pkg/agent/core/ngt/handler/grpc/object_test.go @@ -1188,15 +1188,6 @@ func Test_server_GetObject(t *testing.T) { } } -type ListObjectStreamMock struct { - mock.ServerStreamTestifyMock -} - -func (sssm *ListObjectStreamMock) Send(res *payload.Object_List_Response) error { - args := sssm.Called(res) - return args.Error(0) -} - func Test_server_StreamGetObject(t *testing.T) { t.Parallel() @@ -1258,7 +1249,7 @@ func Test_server_StreamGetObject(t *testing.T) { require.NoError(t, err) // Set mock and expectations - stream := ListObjectStreamMock{} + stream := mock.ListObjectStreamMock{} stream.On("Send", tmock.Anything).Return(nil) // Call the method under test @@ -1302,7 +1293,7 @@ func Test_server_StreamGetObject(t *testing.T) { require.NoError(t, err) // Set mock and expectations - stream := ListObjectStreamMock{} + stream := mock.ListObjectStreamMock{} stream.On("Send", tmock.Anything).Return(status.New(codes.Unknown, "foo").Err()).Once() stream.On("Send", tmock.Anything).Return(status.New(codes.Aborted, "bar").Err()) @@ -1324,7 +1315,7 @@ func Test_server_StreamGetObject(t *testing.T) { _, s := setup(t) // Set mock and expectations - stream := ListObjectStreamMock{} + stream := mock.ListObjectStreamMock{} stream.On("Send", tmock.Anything).Return(nil) // Call the method under test From 467f55fd84c44afbe84b7642c77e7a18b0af88fd Mon Sep 17 00:00:00 2001 From: ykadowak Date: Wed, 2 Aug 2023 05:02:32 +0000 Subject: [PATCH 08/10] refactor --- internal/net/grpc/stream.go | 1 - pkg/agent/core/ngt/handler/grpc/object.go | 35 ++++++++++------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/internal/net/grpc/stream.go b/internal/net/grpc/stream.go index 72a2ecf320..8ef34f82f3 100644 --- a/internal/net/grpc/stream.go +++ b/internal/net/grpc/stream.go @@ -106,7 +106,6 @@ func BidirectionalStream[Q any, R any](ctx context.Context, stream ServerStream, log.Errorf("failed to receive stream message: %v", err) } return finalize() - } if data != nil { eg.Go(safety.RecoverWithoutPanicFunc(func() (err error) { diff --git a/pkg/agent/core/ngt/handler/grpc/object.go b/pkg/agent/core/ngt/handler/grpc/object.go index c2bd134042..86c4a9223e 100644 --- a/pkg/agent/core/ngt/handler/grpc/object.go +++ b/pkg/agent/core/ngt/handler/grpc/object.go @@ -216,35 +216,28 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob ) s.ngt.ListObjectFunc(ctx, func(uuid string, _ uint32, _ int64) bool { vec, ts, err := s.ngt.GetObject(uuid) + var res *payload.Object_List_Response if err != nil { st := status.CreateWithNotFound(fmt.Sprintf("failed to get object with uuid: %s", uuid), err) - - mu.Lock() - err := stream.Send(&payload.Object_List_Response{ + res = &payload.Object_List_Response{ Payload: &payload.Object_List_Response_Status{ Status: st.Proto(), }, - }) - mu.Unlock() - - if err != nil { - emu.Lock() - errs = append(errs, err) - emu.Unlock() } - return true + } else { + res = &payload.Object_List_Response{ + Payload: &payload.Object_List_Response_Vector{ + Vector: &payload.Object_Vector{ + Id: uuid, + Vector: vec, + Timestamp: ts, + }, + }, + } } mu.Lock() - err = stream.Send(&payload.Object_List_Response{ - Payload: &payload.Object_List_Response_Vector{ - Vector: &payload.Object_Vector{ - Id: uuid, - Vector: vec, - Timestamp: ts, - }, - }, - }) + err = stream.Send(res) mu.Unlock() if err != nil { @@ -252,6 +245,8 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob errs = append(errs, err) emu.Unlock() } + + // always return true to continue streaming and let the context cancel the Range when stream closes. return true }) From 2f7289b0c199d9f928b8058cafb82eb35945d926 Mon Sep 17 00:00:00 2001 From: ykadowak Date: Wed, 2 Aug 2023 06:44:31 +0000 Subject: [PATCH 09/10] Use map for accumulating errors --- pkg/agent/core/ngt/handler/grpc/object.go | 37 ++++++++++++++--------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/object.go b/pkg/agent/core/ngt/handler/grpc/object.go index 86c4a9223e..b7057dffc3 100644 --- a/pkg/agent/core/ngt/handler/grpc/object.go +++ b/pkg/agent/core/ngt/handler/grpc/object.go @@ -28,7 +28,6 @@ import ( "github.com/vdaas/vald/internal/net/grpc/errdetails" "github.com/vdaas/vald/internal/net/grpc/status" "github.com/vdaas/vald/internal/observability/trace" - "github.com/vdaas/vald/internal/slices" ) func (s *server) Exists(ctx context.Context, uid *payload.Object_ID) (res *payload.Object_ID, err error) { @@ -211,8 +210,9 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob var ( mu sync.Mutex - emu sync.Mutex + emu sync.RWMutex errs = make([]error, 0, s.ngt.Len()) + emap = make(map[string]struct{}) ) s.ngt.ListObjectFunc(ctx, func(uuid string, _ uint32, _ int64) bool { vec, ts, err := s.ngt.GetObject(uuid) @@ -241,9 +241,15 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob mu.Unlock() if err != nil { - emu.Lock() - errs = append(errs, err) - emu.Unlock() + emu.RLock() + _, ok := emap[err.Error()] + emu.RUnlock() + if !ok { + emu.Lock() + errs = append(errs, err) + emap[err.Error()] = struct{}{} + emu.Unlock() + } } // always return true to continue streaming and let the context cancel the Range when stream closes. @@ -251,17 +257,18 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob }) if len(errs) != 0 { - slices.RemoveDuplicates(errs, func(left, right error) bool { - return left.Error() < right.Error() - }) - err = errors.Join(errs...) - st, msg, err := status.ParseError(err, codes.Internal, "failed to parse StreamListObject final gRPC error response") - if span != nil { - span.RecordError(err) - span.SetAttributes(trace.FromGRPCStatus(st.Code(), msg)...) - span.SetStatus(trace.StatusError, msg) + // Register all the gRPC codes to the span. Doing this because ParseError cannot parse joined error. + for _, e := range errs { + st, msg, err := status.ParseError(e, codes.Internal, "failed to parse StreamListObject final gRPC error response") + if span != nil { + span.RecordError(err) + span.SetAttributes(trace.FromGRPCStatus(st.Code(), msg)...) + span.SetStatus(trace.StatusError, msg) + } } - return err + + // now join all the errors to return + return errors.Join(errs...) } return nil } From d21c1af8a7b671c6a5300b10a0a6131e0dad69bd Mon Sep 17 00:00:00 2001 From: ykadowak Date: Thu, 3 Aug 2023 01:49:33 +0000 Subject: [PATCH 10/10] refactor --- pkg/agent/core/ngt/handler/grpc/object.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/object.go b/pkg/agent/core/ngt/handler/grpc/object.go index b7057dffc3..b7571c3344 100644 --- a/pkg/agent/core/ngt/handler/grpc/object.go +++ b/pkg/agent/core/ngt/handler/grpc/object.go @@ -258,9 +258,9 @@ func (s *server) StreamListObject(_ *payload.Object_List_Request, stream vald.Ob if len(errs) != 0 { // Register all the gRPC codes to the span. Doing this because ParseError cannot parse joined error. - for _, e := range errs { - st, msg, err := status.ParseError(e, codes.Internal, "failed to parse StreamListObject final gRPC error response") - if span != nil { + if span != nil { + for _, e := range errs { + st, msg, err := status.ParseError(e, codes.Internal, "failed to parse StreamListObject final gRPC error response") span.RecordError(err) span.SetAttributes(trace.FromGRPCStatus(st.Code(), msg)...) span.SetStatus(trace.StatusError, msg)