From 95c8e9cfa6ea1d4c3d305c61de349bf6e63774c6 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 4 Jun 2020 12:10:34 +0300 Subject: [PATCH] move cache to datasource_cache --- pkg/cache/cache.go | 22 +------- pkg/datasource/datasource.go | 8 +-- pkg/datasource/datasource_cache.go | 51 +++++++++++++++++++ .../datasource_cache_test.go} | 2 +- pkg/datasource/zabbix.go | 6 +-- pkg/datasource/zabbix_test.go | 2 +- 6 files changed, 61 insertions(+), 30 deletions(-) create mode 100644 pkg/datasource/datasource_cache.go rename pkg/{cache/cache_test.go => datasource/datasource_cache_test.go} (99%) diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 2890927..66e2505 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -1,12 +1,8 @@ package cache import ( - "crypto/sha1" - "encoding/hex" - "encoding/json" "time" - "github.com/grafana/grafana-plugin-sdk-go/backend" cache "github.com/patrickmn/go-cache" ) @@ -19,6 +15,8 @@ const ( DefaultExpiration time.Duration = 0 ) +// TODO: since all methods moved to datasource_cache, this can be removed and replaced by go-cache + // Cache is a abstraction over go-cache. type Cache struct { cache *cache.Cache @@ -40,19 +38,3 @@ func (c *Cache) Set(request string, response interface{}) { func (c *Cache) Get(request string) (interface{}, bool) { return c.cache.Get(request) } - -// HashString converts the given text string to hash string -func HashString(text string) string { - hash := sha1.New() - hash.Write([]byte(text)) - return hex.EncodeToString(hash.Sum(nil)) -} - -// HashDatasourceInfo converts the given datasource info to hash string -func HashDatasourceInfo(dsInfo *backend.DataSourceInstanceSettings) string { - digester := sha1.New() - if err := json.NewEncoder(digester).Encode(dsInfo); err != nil { - panic(err) // This shouldn't be possible but just in case DatasourceInfo changes - } - return hex.EncodeToString(digester.Sum(nil)) -} diff --git a/pkg/datasource/datasource.go b/pkg/datasource/datasource.go index c9ad963..35baa38 100644 --- a/pkg/datasource/datasource.go +++ b/pkg/datasource/datasource.go @@ -27,7 +27,7 @@ type ZabbixDatasourceInstance struct { zabbixAPI *zabbixapi.ZabbixAPI dsInfo *backend.DataSourceInstanceSettings Settings *ZabbixDatasourceSettings - queryCache *cache.Cache + queryCache *DatasourceCache logger log.Logger } @@ -54,7 +54,7 @@ func NewZabbixDatasourceInstance(dsInfo *backend.DataSourceInstanceSettings) (*Z dsInfo: dsInfo, zabbixAPI: zabbixAPI, Settings: zabbixSettings, - queryCache: cache.NewCache(zabbixSettings.CacheTTL, 10*time.Minute), + queryCache: NewDatasourceCache(zabbixSettings.CacheTTL, 10*time.Minute), logger: log.New(), }, nil } @@ -121,11 +121,11 @@ func (ds *ZabbixDatasource) GetDatasource(pluginContext backend.PluginContext) ( dsSettings := pluginContext.DataSourceInstanceSettings dsKey := fmt.Sprintf("%d-%d", pluginContext.OrgID, dsSettings.ID) // Get hash to check if settings changed - dsInfoHash := cache.HashDatasourceInfo(dsSettings) + dsInfoHash := HashDatasourceInfo(dsSettings) if cachedData, ok := ds.datasourceCache.Get(dsKey); ok { if cachedDS, ok := cachedData.(*ZabbixDatasourceInstance); ok { - cachedDSHash := cache.HashDatasourceInfo(cachedDS.dsInfo) + cachedDSHash := HashDatasourceInfo(cachedDS.dsInfo) if cachedDSHash == dsInfoHash { return cachedDS, nil } diff --git a/pkg/datasource/datasource_cache.go b/pkg/datasource/datasource_cache.go new file mode 100644 index 0000000..1e17285 --- /dev/null +++ b/pkg/datasource/datasource_cache.go @@ -0,0 +1,51 @@ +package datasource + +import ( + "crypto/sha1" + "encoding/hex" + "encoding/json" + "time" + + "github.com/alexanderzobnin/grafana-zabbix/pkg/cache" + "github.com/grafana/grafana-plugin-sdk-go/backend" +) + +// DatasourceCache is a cache for datasource instance. +type DatasourceCache struct { + cache *cache.Cache +} + +// NewDatasourceCache creates a DatasourceCache with expiration(ttl) time and cleanupInterval. +func NewDatasourceCache(ttl time.Duration, cleanupInterval time.Duration) *DatasourceCache { + return &DatasourceCache{ + cache.NewCache(ttl, cleanupInterval), + } +} + +// GetAPIRequest gets request response from cache +func (c *DatasourceCache) GetAPIRequest(request *ZabbixAPIRequest) (interface{}, bool) { + requestHash := HashString(request.String()) + return c.cache.Get(requestHash) +} + +// SetAPIRequest writes request response to cache +func (c *DatasourceCache) SetAPIRequest(request *ZabbixAPIRequest, response interface{}) { + requestHash := HashString(request.String()) + c.cache.Set(requestHash, response) +} + +// HashString converts the given text string to hash string +func HashString(text string) string { + hash := sha1.New() + hash.Write([]byte(text)) + return hex.EncodeToString(hash.Sum(nil)) +} + +// HashDatasourceInfo converts the given datasource info to hash string +func HashDatasourceInfo(dsInfo *backend.DataSourceInstanceSettings) string { + digester := sha1.New() + if err := json.NewEncoder(digester).Encode(dsInfo); err != nil { + panic(err) // This shouldn't be possible but just in case DatasourceInfo changes + } + return hex.EncodeToString(digester.Sum(nil)) +} diff --git a/pkg/cache/cache_test.go b/pkg/datasource/datasource_cache_test.go similarity index 99% rename from pkg/cache/cache_test.go rename to pkg/datasource/datasource_cache_test.go index 3314934..dfdd37a 100644 --- a/pkg/cache/cache_test.go +++ b/pkg/datasource/datasource_cache_test.go @@ -1,4 +1,4 @@ -package cache +package datasource import ( "testing" diff --git a/pkg/datasource/zabbix.go b/pkg/datasource/zabbix.go index 622e2f0..c2c3382 100644 --- a/pkg/datasource/zabbix.go +++ b/pkg/datasource/zabbix.go @@ -6,7 +6,6 @@ import ( "regexp" "time" - "github.com/alexanderzobnin/grafana-zabbix/pkg/cache" "github.com/alexanderzobnin/grafana-zabbix/pkg/zabbixapi" simplejson "github.com/bitly/go-simplejson" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -28,9 +27,8 @@ var CachedMethods = map[string]bool{ func (ds *ZabbixDatasourceInstance) ZabbixQuery(ctx context.Context, apiReq *ZabbixAPIRequest) (*simplejson.Json, error) { var resultJson *simplejson.Json var err error - requestHash := cache.HashString(apiReq.String()) - cachedResult, queryExistInCache := ds.queryCache.Get(requestHash) + cachedResult, queryExistInCache := ds.queryCache.GetAPIRequest(apiReq) if !queryExistInCache { resultJson, err = ds.ZabbixRequest(ctx, apiReq.Method, apiReq.Params) if err != nil { @@ -39,7 +37,7 @@ func (ds *ZabbixDatasourceInstance) ZabbixQuery(ctx context.Context, apiReq *Zab if _, ok := CachedMethods[apiReq.Method]; ok { ds.logger.Debug("Write result to cache", "method", apiReq.Method) - ds.queryCache.Set(requestHash, resultJson) + ds.queryCache.SetAPIRequest(apiReq, resultJson) } } else { var ok bool diff --git a/pkg/datasource/zabbix_test.go b/pkg/datasource/zabbix_test.go index e5b6ba7..50e1d9e 100644 --- a/pkg/datasource/zabbix_test.go +++ b/pkg/datasource/zabbix_test.go @@ -50,7 +50,7 @@ func MockZabbixDataSource(body string, statusCode int) *ZabbixDatasourceInstance dsInfo: basicDatasourceInfo, zabbixAPI: zabbixAPI, Settings: zabbixSettings, - queryCache: cache.NewCache(cache.NoExpiration, 10*time.Minute), + queryCache: NewDatasourceCache(cache.NoExpiration, 10*time.Minute), logger: log.New(), } }