diff --git a/cache/examples.json b/cache/examples.json index 63935d4..4dc5a8f 100644 --- a/cache/examples.json +++ b/cache/examples.json @@ -62,5 +62,14 @@ "key": "counter", "value": 0 } + }], + "listKeys": [{ + "title": "List the keys", + "description": "List all the stored keys", + "run_check": true, + "request": {}, + "response": { + "keys": ["counter", "foo"] + } }] } diff --git a/cache/handler/cache.go b/cache/handler/cache.go index 4b6873e..735124b 100644 --- a/cache/handler/cache.go +++ b/cache/handler/cache.go @@ -120,3 +120,16 @@ func (c *Cache) Decrement(ctx context.Context, req *pb.DecrementRequest, rsp *pb return nil } + +func (c *Cache) ListKeys(ctx context.Context, req *pb.ListKeysRequest, rsp *pb.ListKeysResponse) error { + keys, err := cache.Context(ctx).ListKeys() + + if err != nil { + log.Errorf("Error listing keys in cache %s", err) + return errors.InternalServerError("cache.listkeys", "Error listing keys in cache") + } + + rsp.Keys = keys + + return nil +} diff --git a/cache/proto/cache.pb.go b/cache/proto/cache.pb.go index 398ff97..f0ae7df 100644 --- a/cache/proto/cache.pb.go +++ b/cache/proto/cache.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 +// protoc-gen-go v1.27.1 // protoc v3.15.6 // source: proto/cache.proto @@ -20,7 +20,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// Get an item from the cache by key +// Get an item from the cache by key. If key is not found, an empty response is returned. type GetRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -135,7 +135,7 @@ func (x *GetResponse) GetTtl() int64 { return 0 } -// Set an item in the cache +// Set an item in the cache. Overwrites any existing value already set. type SetRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -250,7 +250,7 @@ func (x *SetResponse) GetStatus() string { return "" } -// Delete a value from the cache +// Delete a value from the cache. If key not found a success response is returned. type DeleteRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -347,7 +347,7 @@ func (x *DeleteResponse) GetStatus() string { return "" } -// Increment a value (if its a number) +// Increment a value (if it's a number). If key not found it is equivalent to set. type IncrementRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -355,7 +355,7 @@ type IncrementRequest struct { // The key to increment Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The value to add + // The amount to increment the value by Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` } @@ -412,7 +412,7 @@ type IncrementResponse struct { // The key incremented Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The result value + // The new value Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` } @@ -462,7 +462,7 @@ func (x *IncrementResponse) GetValue() int64 { return 0 } -// Decrement a value (if its a number) +// Decrement a value (if it's a number). If key not found it is equivalent to set. type DecrementRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -470,7 +470,7 @@ type DecrementRequest struct { // The key to decrement Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The delta value to decrement + // The amount to decrement the value by Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` } @@ -525,9 +525,9 @@ type DecrementResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The key of the item + // The key decremented Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The result value of the item + // The new value Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` } @@ -577,6 +577,92 @@ func (x *DecrementResponse) GetValue() int64 { return 0 } +// List all the available keys +type ListKeysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListKeysRequest) Reset() { + *x = ListKeysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_cache_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListKeysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListKeysRequest) ProtoMessage() {} + +func (x *ListKeysRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_cache_proto_msgTypes[10] + 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 ListKeysRequest.ProtoReflect.Descriptor instead. +func (*ListKeysRequest) Descriptor() ([]byte, []int) { + return file_proto_cache_proto_rawDescGZIP(), []int{10} +} + +type ListKeysResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keys []string `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +} + +func (x *ListKeysResponse) Reset() { + *x = ListKeysResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_cache_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListKeysResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListKeysResponse) ProtoMessage() {} + +func (x *ListKeysResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_cache_proto_msgTypes[11] + 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 ListKeysResponse.ProtoReflect.Descriptor instead. +func (*ListKeysResponse) Descriptor() ([]byte, []int) { + return file_proto_cache_proto_rawDescGZIP(), []int{11} +} + +func (x *ListKeysResponse) GetKeys() []string { + if x != nil { + return x.Keys + } + return nil +} + var File_proto_cache_proto protoreflect.FileDescriptor var file_proto_cache_proto_rawDesc = []byte{ @@ -615,27 +701,34 @@ var file_proto_cache_proto_rawDesc = []byte{ 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x32, 0xa4, 0x02, 0x0a, 0x05, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x2e, 0x0a, 0x03, 0x47, - 0x65, 0x74, 0x12, 0x11, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x03, 0x53, - 0x65, 0x74, 0x12, 0x11, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x53, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x61, - 0x63, 0x68, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x17, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x61, 0x63, - 0x68, 0x65, 0x2e, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x09, 0x44, 0x65, 0x63, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x12, 0x17, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x44, 0x65, 0x63, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, - 0x61, 0x63, 0x68, 0x65, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x61, 0x63, 0x68, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x26, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x32, 0xe3, 0x02, 0x0a, + 0x05, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x2e, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x11, 0x2e, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x12, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x12, 0x11, 0x2e, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x12, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x14, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x40, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x17, 0x2e, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x49, 0x6e, + 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x40, 0x0a, 0x09, 0x44, 0x65, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x17, + 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, + 0x44, 0x65, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x12, + 0x16, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x63, 0x61, + 0x63, 0x68, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -650,7 +743,7 @@ func file_proto_cache_proto_rawDescGZIP() []byte { return file_proto_cache_proto_rawDescData } -var file_proto_cache_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_proto_cache_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_proto_cache_proto_goTypes = []interface{}{ (*GetRequest)(nil), // 0: cache.GetRequest (*GetResponse)(nil), // 1: cache.GetResponse @@ -662,23 +755,27 @@ var file_proto_cache_proto_goTypes = []interface{}{ (*IncrementResponse)(nil), // 7: cache.IncrementResponse (*DecrementRequest)(nil), // 8: cache.DecrementRequest (*DecrementResponse)(nil), // 9: cache.DecrementResponse + (*ListKeysRequest)(nil), // 10: cache.ListKeysRequest + (*ListKeysResponse)(nil), // 11: cache.ListKeysResponse } var file_proto_cache_proto_depIdxs = []int32{ - 0, // 0: cache.Cache.Get:input_type -> cache.GetRequest - 2, // 1: cache.Cache.Set:input_type -> cache.SetRequest - 4, // 2: cache.Cache.Delete:input_type -> cache.DeleteRequest - 6, // 3: cache.Cache.Increment:input_type -> cache.IncrementRequest - 8, // 4: cache.Cache.Decrement:input_type -> cache.DecrementRequest - 1, // 5: cache.Cache.Get:output_type -> cache.GetResponse - 3, // 6: cache.Cache.Set:output_type -> cache.SetResponse - 5, // 7: cache.Cache.Delete:output_type -> cache.DeleteResponse - 7, // 8: cache.Cache.Increment:output_type -> cache.IncrementResponse - 9, // 9: cache.Cache.Decrement:output_type -> cache.DecrementResponse - 5, // [5:10] is the sub-list for method output_type - 0, // [0:5] 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 + 0, // 0: cache.Cache.Get:input_type -> cache.GetRequest + 2, // 1: cache.Cache.Set:input_type -> cache.SetRequest + 4, // 2: cache.Cache.Delete:input_type -> cache.DeleteRequest + 6, // 3: cache.Cache.Increment:input_type -> cache.IncrementRequest + 8, // 4: cache.Cache.Decrement:input_type -> cache.DecrementRequest + 10, // 5: cache.Cache.ListKeys:input_type -> cache.ListKeysRequest + 1, // 6: cache.Cache.Get:output_type -> cache.GetResponse + 3, // 7: cache.Cache.Set:output_type -> cache.SetResponse + 5, // 8: cache.Cache.Delete:output_type -> cache.DeleteResponse + 7, // 9: cache.Cache.Increment:output_type -> cache.IncrementResponse + 9, // 10: cache.Cache.Decrement:output_type -> cache.DecrementResponse + 11, // 11: cache.Cache.ListKeys:output_type -> cache.ListKeysResponse + 6, // [6:12] is the sub-list for method output_type + 0, // [0:6] 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 } func init() { file_proto_cache_proto_init() } @@ -807,6 +904,30 @@ func file_proto_cache_proto_init() { return nil } } + file_proto_cache_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListKeysRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_cache_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListKeysResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -814,7 +935,7 @@ func file_proto_cache_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_cache_proto_rawDesc, NumEnums: 0, - NumMessages: 10, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, diff --git a/cache/proto/cache.pb.micro.go b/cache/proto/cache.pb.micro.go index 18cbade..8409042 100644 --- a/cache/proto/cache.pb.micro.go +++ b/cache/proto/cache.pb.micro.go @@ -47,6 +47,7 @@ type CacheService interface { Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) Increment(ctx context.Context, in *IncrementRequest, opts ...client.CallOption) (*IncrementResponse, error) Decrement(ctx context.Context, in *DecrementRequest, opts ...client.CallOption) (*DecrementResponse, error) + ListKeys(ctx context.Context, in *ListKeysRequest, opts ...client.CallOption) (*ListKeysResponse, error) } type cacheService struct { @@ -111,6 +112,16 @@ func (c *cacheService) Decrement(ctx context.Context, in *DecrementRequest, opts return out, nil } +func (c *cacheService) ListKeys(ctx context.Context, in *ListKeysRequest, opts ...client.CallOption) (*ListKeysResponse, error) { + req := c.c.NewRequest(c.name, "Cache.ListKeys", in) + out := new(ListKeysResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Cache service type CacheHandler interface { @@ -119,6 +130,7 @@ type CacheHandler interface { Delete(context.Context, *DeleteRequest, *DeleteResponse) error Increment(context.Context, *IncrementRequest, *IncrementResponse) error Decrement(context.Context, *DecrementRequest, *DecrementResponse) error + ListKeys(context.Context, *ListKeysRequest, *ListKeysResponse) error } func RegisterCacheHandler(s server.Server, hdlr CacheHandler, opts ...server.HandlerOption) error { @@ -128,6 +140,7 @@ func RegisterCacheHandler(s server.Server, hdlr CacheHandler, opts ...server.Han Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error Increment(ctx context.Context, in *IncrementRequest, out *IncrementResponse) error Decrement(ctx context.Context, in *DecrementRequest, out *DecrementResponse) error + ListKeys(ctx context.Context, in *ListKeysRequest, out *ListKeysResponse) error } type Cache struct { cache @@ -159,3 +172,7 @@ func (h *cacheHandler) Increment(ctx context.Context, in *IncrementRequest, out func (h *cacheHandler) Decrement(ctx context.Context, in *DecrementRequest, out *DecrementResponse) error { return h.CacheHandler.Decrement(ctx, in, out) } + +func (h *cacheHandler) ListKeys(ctx context.Context, in *ListKeysRequest, out *ListKeysResponse) error { + return h.CacheHandler.ListKeys(ctx, in, out) +} diff --git a/cache/proto/cache.proto b/cache/proto/cache.proto index 7d30e80..70763a8 100644 --- a/cache/proto/cache.proto +++ b/cache/proto/cache.proto @@ -10,6 +10,7 @@ service Cache { rpc Delete(DeleteRequest) returns (DeleteResponse) {} rpc Increment(IncrementRequest) returns (IncrementResponse) {} rpc Decrement(DecrementRequest) returns (DecrementResponse) {} + rpc ListKeys(ListKeysRequest) returns (ListKeysResponse) {} } // Get an item from the cache by key. If key is not found, an empty response is returned. @@ -82,3 +83,12 @@ message DecrementResponse { // The new value int64 value = 2; } + +// List all the available keys +message ListKeysRequest { + +} + +message ListKeysResponse { + repeated string keys = 1; +} diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 8f3cde3..e029b1a 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "sync" "time" @@ -24,11 +25,12 @@ type Cache interface { Delete(key string) error Increment(key string, val int64) (int64, error) Decrement(key string, val int64) (int64, error) + ListKeys() ([]string, error) Close() error } type cache struct { - sync.Mutex + sync.RWMutex closed chan bool LRU *lru.Cache Disk *diskv.Diskv @@ -259,6 +261,30 @@ func (c *cache) Decrement(key string, value int64) (int64, error) { return val, nil } +func (c *cache) ListKeys() ([]string, error) { + c.RLock() + defer c.RUnlock() + + if c.Store == nil { + c.Store = store.DefaultStore + } + + prefix := c.Key("") + + recKeys, err := c.Store.List(store.ListPrefix(prefix)) + if err != nil { + return nil, err + } + + var keys []string + + for _, key := range recKeys { + keys = append(keys, strings.TrimPrefix(key, prefix)) + } + + return keys, nil +} + func Context(ctx context.Context) Cache { return DefaultCache.Context(ctx) } @@ -282,3 +308,7 @@ func Increment(key string, val int64) (int64, error) { func Decrement(key string, val int64) (int64, error) { return DefaultCache.Decrement(key, val) } + +func ListKeys() ([]string, error) { + return DefaultCache.ListKeys() +}