-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added new cache package for query service (#6733)
* feat: added new cache package for query service * feat: handle type checking for inmemory * feat: some copy corrections * feat: added inmemory test cases * chore: some renaming * feat: added redis handling * chore: add redis tests * feat(cache): refactor the code * feat(cache): refactor the code * feat(cache): added defaults for redis config * feat(cache): update makefile to run all tetss * feat(cache): update tests and docs * feat(cache): update tests and docs * feat(cache): handle signoz web flag * feat(cache): handle signoz web flag * feat(cache): handle signoz web flag
- Loading branch information
1 parent
c5938b6
commit 4967696
Showing
13 changed files
with
830 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -190,4 +190,4 @@ check-no-ee-references: | |
fi | ||
|
||
test: | ||
go test ./pkg/query-service/... | ||
go test ./pkg/... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package cache | ||
|
||
import ( | ||
"context" | ||
"encoding" | ||
"fmt" | ||
"reflect" | ||
"time" | ||
) | ||
|
||
// cacheable entity | ||
type CacheableEntity interface { | ||
encoding.BinaryMarshaler | ||
encoding.BinaryUnmarshaler | ||
} | ||
|
||
func WrapCacheableEntityErrors(rt reflect.Type, caller string) error { | ||
if rt == nil { | ||
return fmt.Errorf("%s: (nil)", caller) | ||
} | ||
|
||
if rt.Kind() != reflect.Pointer { | ||
return fmt.Errorf("%s: (non-pointer \"%s\")", caller, rt.String()) | ||
} | ||
|
||
return fmt.Errorf("%s: (nil \"%s\")", caller, rt.String()) | ||
|
||
} | ||
|
||
// cache status | ||
type RetrieveStatus int | ||
|
||
const ( | ||
RetrieveStatusHit = RetrieveStatus(iota) | ||
RetrieveStatusPartialHit | ||
RetrieveStatusRangeMiss | ||
RetrieveStatusKeyMiss | ||
RetrieveStatusRevalidated | ||
|
||
RetrieveStatusError | ||
) | ||
|
||
func (s RetrieveStatus) String() string { | ||
switch s { | ||
case RetrieveStatusHit: | ||
return "hit" | ||
case RetrieveStatusPartialHit: | ||
return "partial hit" | ||
case RetrieveStatusRangeMiss: | ||
return "range miss" | ||
case RetrieveStatusKeyMiss: | ||
return "key miss" | ||
case RetrieveStatusRevalidated: | ||
return "revalidated" | ||
case RetrieveStatusError: | ||
return "error" | ||
default: | ||
return "unknown" | ||
} | ||
} | ||
|
||
// cache interface | ||
type Cache interface { | ||
Connect(ctx context.Context) error | ||
Store(ctx context.Context, cacheKey string, data CacheableEntity, ttl time.Duration) error | ||
Retrieve(ctx context.Context, cacheKey string, dest CacheableEntity, allowExpired bool) (RetrieveStatus, error) | ||
SetTTL(ctx context.Context, cacheKey string, ttl time.Duration) | ||
Remove(ctx context.Context, cacheKey string) | ||
BulkRemove(ctx context.Context, cacheKeys []string) | ||
Close(ctx context.Context) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package cache | ||
|
||
import ( | ||
"time" | ||
|
||
go_cache "github.com/patrickmn/go-cache" | ||
"go.signoz.io/signoz/pkg/confmap" | ||
) | ||
|
||
// Config satisfies the confmap.Config interface | ||
var _ confmap.Config = (*Config)(nil) | ||
|
||
type Memory struct { | ||
TTL time.Duration `mapstructure:"ttl"` | ||
CleanupInterval time.Duration `mapstructure:"cleanupInterval"` | ||
} | ||
|
||
type Redis struct { | ||
Host string `mapstructure:"host"` | ||
Port int `mapstructure:"port"` | ||
Password string `mapstructure:"password"` | ||
DB int `mapstructure:"db"` | ||
} | ||
|
||
type Config struct { | ||
Provider string `mapstructure:"provider"` | ||
Memory Memory `mapstructure:"memory"` | ||
Redis Redis `mapstructure:"redis"` | ||
} | ||
|
||
func (c *Config) NewWithDefaults() confmap.Config { | ||
return &Config{ | ||
Provider: "memory", | ||
Memory: Memory{ | ||
TTL: go_cache.NoExpiration, | ||
CleanupInterval: 1 * time.Minute, | ||
}, | ||
Redis: Redis{ | ||
Host: "localhost", | ||
Port: 6379, | ||
Password: "", | ||
DB: 0, | ||
}, | ||
} | ||
} | ||
|
||
func (c *Config) Validate() error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package memory | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"reflect" | ||
"time" | ||
|
||
go_cache "github.com/patrickmn/go-cache" | ||
_cache "go.signoz.io/signoz/pkg/cache" | ||
) | ||
|
||
type cache struct { | ||
cc *go_cache.Cache | ||
} | ||
|
||
func New(opts *_cache.Memory) *cache { | ||
return &cache{cc: go_cache.New(opts.TTL, opts.CleanupInterval)} | ||
} | ||
|
||
// Connect does nothing | ||
func (c *cache) Connect(_ context.Context) error { | ||
return nil | ||
} | ||
|
||
// Store stores the data in the cache | ||
func (c *cache) Store(_ context.Context, cacheKey string, data _cache.CacheableEntity, ttl time.Duration) error { | ||
// check if the data being passed is a pointer and is not nil | ||
rv := reflect.ValueOf(data) | ||
if rv.Kind() != reflect.Pointer || rv.IsNil() { | ||
return _cache.WrapCacheableEntityErrors(reflect.TypeOf(data), "inmemory") | ||
} | ||
|
||
c.cc.Set(cacheKey, data, ttl) | ||
return nil | ||
} | ||
|
||
// Retrieve retrieves the data from the cache | ||
func (c *cache) Retrieve(_ context.Context, cacheKey string, dest _cache.CacheableEntity, allowExpired bool) (_cache.RetrieveStatus, error) { | ||
// check if the destination being passed is a pointer and is not nil | ||
dstv := reflect.ValueOf(dest) | ||
if dstv.Kind() != reflect.Pointer || dstv.IsNil() { | ||
return _cache.RetrieveStatusError, _cache.WrapCacheableEntityErrors(reflect.TypeOf(dest), "inmemory") | ||
} | ||
|
||
// check if the destination value is settable | ||
if !dstv.Elem().CanSet() { | ||
return _cache.RetrieveStatusError, fmt.Errorf("destination value is not settable, %s", dstv.Elem()) | ||
} | ||
|
||
data, found := c.cc.Get(cacheKey) | ||
if !found { | ||
return _cache.RetrieveStatusKeyMiss, nil | ||
} | ||
|
||
// check the type compatbility between the src and dest | ||
srcv := reflect.ValueOf(data) | ||
if !srcv.Type().AssignableTo(dstv.Type()) { | ||
return _cache.RetrieveStatusError, fmt.Errorf("src type is not assignable to dst type") | ||
} | ||
|
||
// set the value to from src to dest | ||
dstv.Elem().Set(srcv.Elem()) | ||
return _cache.RetrieveStatusHit, nil | ||
} | ||
|
||
// SetTTL sets the TTL for the cache entry | ||
func (c *cache) SetTTL(_ context.Context, cacheKey string, ttl time.Duration) { | ||
item, found := c.cc.Get(cacheKey) | ||
if !found { | ||
return | ||
} | ||
c.cc.Replace(cacheKey, item, ttl) | ||
} | ||
|
||
// Remove removes the cache entry | ||
func (c *cache) Remove(_ context.Context, cacheKey string) { | ||
c.cc.Delete(cacheKey) | ||
} | ||
|
||
// BulkRemove removes the cache entries | ||
func (c *cache) BulkRemove(_ context.Context, cacheKeys []string) { | ||
for _, cacheKey := range cacheKeys { | ||
c.cc.Delete(cacheKey) | ||
} | ||
} | ||
|
||
// Close does nothing | ||
func (c *cache) Close(_ context.Context) error { | ||
return nil | ||
} | ||
|
||
// Configuration returns the cache configuration | ||
func (c *cache) Configuration() *_cache.Memory { | ||
return nil | ||
} |
Oops, something went wrong.