diff --git a/conf/defaults.ini b/conf/defaults.ini index df02e01235b..d77f980f806 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -106,6 +106,18 @@ path = grafana.db # For "sqlite3" only. cache mode setting used for connecting to the database cache_mode = private +#################################### Cache server ############################# +[cache_server] +# Either "memory", "redis", "memcache" or "database" default is "database" +type = database + +# cache connectionstring options +# memory: no config required. Should only be used on single install grafana. +# database: will use Grafana primary database. +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana` +# memcache: 127.0.0.1:11211 +connstr = + #################################### Session ############################# [session] # Either "memory", "file", "redis", "mysql", "postgres", "memcache", default is "file" diff --git a/pkg/infra/distcache/database_storage_integration_test.go b/pkg/infra/distcache/database_storage_integration_test.go deleted file mode 100644 index fac430e7e8d..00000000000 --- a/pkg/infra/distcache/database_storage_integration_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package distcache - -import "testing" - -func TestIntegrationDatabaseCacheStorage(t *testing.T) { - runTestsForClient(t, createTestClient(t, "database")) -} diff --git a/pkg/infra/distcache/distcache.go b/pkg/infra/distcache/distcache.go index d21ada1e6a3..ee824ae4c52 100644 --- a/pkg/infra/distcache/distcache.go +++ b/pkg/infra/distcache/distcache.go @@ -6,9 +6,10 @@ import ( "errors" "time" + "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/services/sqlstore" - redis "gopkg.in/redis.v2" "github.com/grafana/grafana/pkg/registry" ) @@ -25,30 +26,21 @@ func init() { func (ds *DistributedCache) Init() error { ds.log = log.New("distributed.cache") - ds.Client = createClient(CacheOpts{}, ds.SQLStore) + ds.Client = createClient(ds.Cfg.CacheOptions, ds.SQLStore) return nil } -type CacheOpts struct { - name string -} - -func createClient(opts CacheOpts, sqlstore *sqlstore.SqlStore) cacheStorage { - if opts.name == "redis" { - opt := &redis.Options{ - Network: "tcp", - Addr: "localhost:6379", - } - - return newRedisStorage(redis.NewClient(opt)) +func createClient(opts *setting.CacheOpts, sqlstore *sqlstore.SqlStore) cacheStorage { + if opts.Name == "redis" { + return newRedisStorage(opts) } - if opts.name == "memcache" { - return newMemcacheStorage("localhost:11211") + if opts.Name == "memcache" { + return newMemcacheStorage(opts) } - if opts.name == "memory" { + if opts.Name == "memory" { return newMemoryStorage() } @@ -60,6 +52,7 @@ type DistributedCache struct { log log.Logger Client cacheStorage SQLStore *sqlstore.SqlStore `inject:""` + Cfg *setting.Cfg `inject:""` } type cachedItem struct { diff --git a/pkg/infra/distcache/distcache_test.go b/pkg/infra/distcache/distcache_test.go index 33a6d2c9c7b..f6ed13d4f06 100644 --- a/pkg/infra/distcache/distcache_test.go +++ b/pkg/infra/distcache/distcache_test.go @@ -8,6 +8,7 @@ import ( "github.com/bmizerany/assert" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/setting" ) type CacheableStruct struct { @@ -19,11 +20,34 @@ func init() { gob.Register(CacheableStruct{}) } -func createTestClient(t *testing.T, name string) cacheStorage { +func createTestClient(t *testing.T, opts *setting.CacheOpts, sqlstore *sqlstore.SqlStore) cacheStorage { t.Helper() - sqlstore := sqlstore.InitTestDB(t) - return createClient(CacheOpts{name: name}, sqlstore) + dc := &DistributedCache{ + SQLStore: sqlstore, + Cfg: &setting.Cfg{ + CacheOptions: opts, + }, + } + + err := dc.Init() + if err != nil { + t.Fatalf("failed to init client for test. error: %v", err) + } + + return dc.Client +} + +func TestCachedBasedOnConfig(t *testing.T) { + + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ + HomePath: "../../../", + }) + + client := createTestClient(t, cfg.CacheOptions, sqlstore.InitTestDB(t)) + + runTestsForClient(t, client) } func runTestsForClient(t *testing.T, client cacheStorage) { diff --git a/pkg/infra/distcache/memcached_storage.go b/pkg/infra/distcache/memcached_storage.go index 7f97a043628..df1346bf350 100644 --- a/pkg/infra/distcache/memcached_storage.go +++ b/pkg/infra/distcache/memcached_storage.go @@ -4,15 +4,16 @@ import ( "time" "github.com/bradfitz/gomemcache/memcache" + "github.com/grafana/grafana/pkg/setting" ) type memcacheStorage struct { c *memcache.Client } -func newMemcacheStorage(connStr string) *memcacheStorage { +func newMemcacheStorage(opts *setting.CacheOpts) *memcacheStorage { return &memcacheStorage{ - c: memcache.New(connStr), + c: memcache.New(opts.ConnStr), } } diff --git a/pkg/infra/distcache/memcached_storage_test.go b/pkg/infra/distcache/memcached_storage_test.go index de784730e4a..3f885700cb4 100644 --- a/pkg/infra/distcache/memcached_storage_test.go +++ b/pkg/infra/distcache/memcached_storage_test.go @@ -1,7 +1,12 @@ package distcache -import "testing" +import ( + "testing" + + "github.com/grafana/grafana/pkg/setting" +) func TestMemcachedCacheStorage(t *testing.T) { - runTestsForClient(t, createTestClient(t, "memcache")) + opts := &setting.CacheOpts{Name: "memcache", ConnStr: "localhost:11211"} + runTestsForClient(t, createTestClient(t, opts, nil)) } diff --git a/pkg/infra/distcache/memory_storage_test.go b/pkg/infra/distcache/memory_storage_test.go index cbf4c3790af..5318b7c19b8 100644 --- a/pkg/infra/distcache/memory_storage_test.go +++ b/pkg/infra/distcache/memory_storage_test.go @@ -1,7 +1,12 @@ package distcache -import "testing" +import ( + "testing" + + "github.com/grafana/grafana/pkg/setting" +) func TestMemoryCacheStorage(t *testing.T) { - runTestsForClient(t, createTestClient(t, "memory")) + opts := &setting.CacheOpts{Name: "memory"} + runTestsForClient(t, createTestClient(t, opts, nil)) } diff --git a/pkg/infra/distcache/redis_storage.go b/pkg/infra/distcache/redis_storage.go index bb21b26473e..4e6a8b6d325 100644 --- a/pkg/infra/distcache/redis_storage.go +++ b/pkg/infra/distcache/redis_storage.go @@ -3,6 +3,7 @@ package distcache import ( "time" + "github.com/grafana/grafana/pkg/setting" redis "gopkg.in/redis.v2" ) @@ -10,8 +11,12 @@ type redisStorage struct { c *redis.Client } -func newRedisStorage(c *redis.Client) *redisStorage { - return &redisStorage{c: c} +func newRedisStorage(opts *setting.CacheOpts) *redisStorage { + opt := &redis.Options{ + Network: "tcp", + Addr: opts.ConnStr, + } + return &redisStorage{c: redis.NewClient(opt)} } // Set sets value to given key in session. diff --git a/pkg/infra/distcache/redis_storage_test.go b/pkg/infra/distcache/redis_storage_test.go index b33d2b22e53..7c63ce46b38 100644 --- a/pkg/infra/distcache/redis_storage_test.go +++ b/pkg/infra/distcache/redis_storage_test.go @@ -1,7 +1,13 @@ package distcache -import "testing" +import ( + "testing" + + "github.com/grafana/grafana/pkg/setting" +) func TestRedisCacheStorage(t *testing.T) { - runTestsForClient(t, createTestClient(t, "redis")) + + opts := &setting.CacheOpts{Name: "redis", ConnStr: "localhost:6379"} + runTestsForClient(t, createTestClient(t, opts, nil)) } diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 5d44a3585dc..f25f2211b40 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -240,6 +240,9 @@ type Cfg struct { // User EditorsCanOwn bool + + // DistributedCache + CacheOptions *CacheOpts } type CommandLineArgs struct { @@ -779,9 +782,22 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { enterprise := iniFile.Section("enterprise") cfg.EnterpriseLicensePath = enterprise.Key("license_path").MustString(filepath.Join(cfg.DataPath, "license.jwt")) + cacheServer := iniFile.Section("cache_server") + //cfg.DistCacheType = cacheServer.Key("type").MustString("database") + //cfg.DistCacheConnStr = cacheServer.Key("connstr").MustString("") + cfg.CacheOptions = &CacheOpts{ + Name: cacheServer.Key("type").MustString("database"), + ConnStr: cacheServer.Key("connstr").MustString(""), + } + return nil } +type CacheOpts struct { + Name string + ConnStr string +} + func (cfg *Cfg) readSessionConfig() { sec := cfg.Raw.Section("session") SessionOptions = session.Options{}