Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added new cache package for query service #6733

Merged
merged 20 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ee/query-service/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/migrate"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/pkg/signoz"
"go.signoz.io/signoz/pkg/web"

licensepkg "go.signoz.io/signoz/ee/query-service/license"
Expand Down Expand Up @@ -62,6 +63,7 @@ import (
const AppDbEngine = "sqlite"

type ServerOptions struct {
SigNoz *signoz.SigNoz
PromConfigPath string
SkipTopLvlOpsPath string
HTTPHostPort string
Expand Down Expand Up @@ -109,7 +111,7 @@ func (s Server) HealthCheckStatus() chan healthcheck.Status {
}

// NewServer creates and initializes Server
func NewServer(serverOptions *ServerOptions, web *web.Web) (*Server, error) {
func NewServer(serverOptions *ServerOptions) (*Server, error) {

modelDao, err := dao.InitDao("sqlite", baseconst.RELATIONAL_DATASOURCE_PATH)
if err != nil {
Expand Down Expand Up @@ -291,7 +293,7 @@ func NewServer(serverOptions *ServerOptions, web *web.Web) (*Server, error) {
usageManager: usageManager,
}

httpServer, err := s.createPublicServer(apiHandler, web)
httpServer, err := s.createPublicServer(apiHandler, serverOptions.SigNoz.Web)

if err != nil {
return nil, err
Expand Down
11 changes: 6 additions & 5 deletions ee/query-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/migrate"
"go.signoz.io/signoz/pkg/query-service/version"
signozweb "go.signoz.io/signoz/pkg/web"
"go.signoz.io/signoz/pkg/signoz"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

Expand Down Expand Up @@ -148,12 +148,13 @@ func main() {
zap.L().Fatal("Failed to create config", zap.Error(err))
}

web, err := signozweb.New(zap.L(), config.Web)
if err != nil && !skipWebFrontend {
zap.L().Fatal("Failed to create web", zap.Error(err))
vikrantgupta25 marked this conversation as resolved.
Show resolved Hide resolved
signoz, err := signoz.New(config)
if err != nil {
zap.L().Fatal("Failed to create signoz struct", zap.Error(err))
}

serverOptions := &app.ServerOptions{
SigNoz: signoz,
HTTPHostPort: baseconst.HTTPHostPort,
PromConfigPath: promConfigPath,
SkipTopLvlOpsPath: skipTopLvlOpsPath,
Expand Down Expand Up @@ -188,7 +189,7 @@ func main() {
zap.L().Info("Migration successful")
}

server, err := app.NewServer(serverOptions, web)
server, err := app.NewServer(serverOptions)
if err != nil {
zap.L().Fatal("Failed to create server", zap.Error(err))
}
Expand Down
70 changes: 70 additions & 0 deletions pkg/cache/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package cache
vikrantgupta25 marked this conversation as resolved.
Show resolved Hide resolved

import (
"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() error
Store(cacheKey string, data CacheableEntity, ttl time.Duration) error
Retrieve(cacheKey string, dest CacheableEntity, allowExpired bool) (RetrieveStatus, error)
SetTTL(cacheKey string, ttl time.Duration)
Remove(cacheKey string)
BulkRemove(cacheKeys []string)
Close() error
}
49 changes: 49 additions & 0 deletions pkg/cache/config.go
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
}
95 changes: 95 additions & 0 deletions pkg/cache/strategy/memory/memory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package memory

import (
"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 {
vikrantgupta25 marked this conversation as resolved.
Show resolved Hide resolved
return &cache{cc: go_cache.New(opts.TTL, opts.CleanupInterval)}
}

// Connect does nothing
func (c *cache) Connect() error {
return nil
}

// Store stores the data in the cache
func (c *cache) Store(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(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(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(cacheKey string) {
c.cc.Delete(cacheKey)
}

// BulkRemove removes the cache entries
func (c *cache) BulkRemove(cacheKeys []string) {
for _, cacheKey := range cacheKeys {
c.cc.Delete(cacheKey)
}
}

// Close does nothing
func (c *cache) Close() error {
return nil
}

// Configuration returns the cache configuration
func (c *cache) Configuration() *_cache.Memory {
return nil
}
Loading
Loading