[MM 19840] Create a Cache Interface abstraction to support multiple cache backends (#13384)

* Refactor to use structured logging

* Properly formatted with gofmt

* created interface Cache, but construction of cache is still coupled.

* Implementing cache factories to build caches

* Simple redis implementation without error handling. Keys and values by default are string

* refactor NewLocalCacheLayer to inject cache factory

* Removed redis impl to focus on cache abstraction

* CacheFactory injected on sqlsupplier and saved in Store struct

* remove useless private method

* replace concrete declaration of lru cache to cache abstraction

* discard spaces

* Renamed factory to provider because concrete implementations of factories may hold an state (such as a redis client for example)

* refactor to include all caches in the same package cache and subpackages

* method close cache. This method will be used for concrete implementations that need to release resources (close a connection, etc)

* closing cacheprovider and releasing resources while closing sql store

* fixed merge conflict fail

* gofmt files

* remove unused property from post_store

* naming refactor to avoid stutter. Added godocs on interface

* Store doesnt know anything about the cache and provider. Cache provider will be built after loading config and injected in localCacheLayer

* fixed broken test

* cache provider initialized before RunOldAppInitialization which initializes the localcachelayer

* move statusCache to server to initialize it with the new cache provider

* update terms_service and channel_layer to have new cacheProvider

* gofmt

* Add Connect method to the cache provider

* mock cacheprovider in user_layer_test

Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Hector
2020-01-09 09:57:28 +01:00
коммит произвёл Jesús Espino
родитель 1909fd6607
Коммит 62b57143c8
31 изменённых файлов: 572 добавлений и 177 удалений

Просмотреть файл

@@ -7,12 +7,12 @@ import (
"net/http"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/utils"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
)
const OPEN_GRAPH_METADATA_CACHE_SIZE = 10000
var openGraphDataCache = utils.NewLru(OPEN_GRAPH_METADATA_CACHE_SIZE)
var openGraphDataCache = lru.New(OPEN_GRAPH_METADATA_CACHE_SIZE)
func (api *API) InitOpenGraph() {
api.BaseRoutes.OpenGraph.Handle("", api.ApiSessionRequired(getOpenGraphMetadata)).Methods("POST")

Просмотреть файл

@@ -13,8 +13,8 @@ import (
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/services/filesstore"
"github.com/mattermost/mattermost-server/v5/utils"
)
const (
@@ -23,7 +23,7 @@ const (
MAX_SERVER_BUSY_SECONDS = 86400
)
var redirectLocationDataCache = utils.NewLru(REDIRECT_LOCATION_CACHE_SIZE)
var redirectLocationDataCache = lru.New(REDIRECT_LOCATION_CACHE_SIZE)
func (api *API) InitSystem() {
api.BaseRoutes.System.Handle("/ping", api.ApiHandler(getSystemPing)).Methods("GET")

Просмотреть файл

@@ -150,7 +150,7 @@ func (a *App) InvalidateAllCaches() *model.AppError {
func (a *App) InvalidateAllCachesSkipSend() {
mlog.Info("Purging all caches")
a.Srv.sessionCache.Purge()
ClearStatusCache()
a.Srv.statusCache.Purge()
a.Srv.Store.Team().ClearCaches()
a.Srv.Store.Channel().ClearCaches()
a.Srv.Store.User().ClearCaches()

Просмотреть файл

@@ -645,7 +645,7 @@ func (a *App) getMentionKeywordsInChannel(profiles map[string]*model.User, allow
keywords,
profile,
channelMemberNotifyPropsMap[profile.Id],
GetStatusFromCache(profile.Id),
a.GetStatusFromCache(profile.Id),
allowChannelMentions,
)
}

Просмотреть файл

@@ -15,7 +15,7 @@ import (
"github.com/dyatlov/go-opengraph/opengraph"
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/utils"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/utils/imgutils"
"github.com/mattermost/mattermost-server/v5/utils/markdown"
)
@@ -24,7 +24,7 @@ const LINK_CACHE_SIZE = 10000
const LINK_CACHE_DURATION = 3600
const MaxMetadataImageSize = MaxOpenGraphResponseSize
var linkCache = utils.NewLru(LINK_CACHE_SIZE)
var linkCache = lru.New(LINK_CACHE_SIZE)
func (a *App) InitPostMetadata() {
// Dump any cached links if the proxy settings have changed so image URLs can be updated

Просмотреть файл

@@ -30,6 +30,8 @@ import (
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/plugin"
"github.com/mattermost/mattermost-server/v5/services/cache"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/services/httpservice"
"github.com/mattermost/mattermost-server/v5/services/imageproxy"
"github.com/mattermost/mattermost-server/v5/services/timezones"
@@ -86,8 +88,9 @@ type Server struct {
newStore func() store.Store
htmlTemplateWatcher *utils.HTMLTemplateWatcher
sessionCache *utils.Cache
seenPendingPostIdsCache *utils.Cache
sessionCache cache.Cache
seenPendingPostIdsCache cache.Cache
statusCache cache.Cache
configListenerId string
licenseListenerId string
logListenerId string
@@ -129,18 +132,18 @@ type Server struct {
Metrics einterfaces.MetricsInterface
Notification einterfaces.NotificationInterface
Saml einterfaces.SamlInterface
CacheProvider cache.Provider
}
func NewServer(options ...Option) (*Server, error) {
rootRouter := mux.NewRouter()
s := &Server{
goroutineExitSignal: make(chan struct{}, 1),
RootRouter: rootRouter,
licenseListeners: map[string]func(){},
sessionCache: utils.NewLru(model.SESSION_CACHE_SIZE),
seenPendingPostIdsCache: utils.NewLru(PENDING_POST_IDS_CACHE_SIZE),
clientConfig: make(map[string]string),
goroutineExitSignal: make(chan struct{}, 1),
RootRouter: rootRouter,
licenseListeners: map[string]func(){},
clientConfig: make(map[string]string),
}
for _, option := range options {
if err := option(s); err != nil {
@@ -188,6 +191,16 @@ func NewServer(options ...Option) (*Server, error) {
return nil, errors.Wrapf(err, "unable to load Mattermost translation files")
}
// at the moment we only have this implementation
// in the future the cache provider will be built based on the loaded config
s.CacheProvider = new(lru.CacheProvider)
s.CacheProvider.Connect()
s.sessionCache = s.CacheProvider.NewCache(model.SESSION_CACHE_SIZE)
s.seenPendingPostIdsCache = s.CacheProvider.NewCache(PENDING_POST_IDS_CACHE_SIZE)
s.statusCache = s.CacheProvider.NewCache(model.STATUS_CACHE_SIZE)
err := s.RunOldAppInitialization()
if err != nil {
return nil, err
@@ -394,6 +407,10 @@ func (s *Server) Shutdown() error {
s.Store.Close()
}
if s.CacheProvider != nil {
s.CacheProvider.Close()
}
mlog.Info("Server stopped")
return nil
}

Просмотреть файл

@@ -64,7 +64,7 @@ func (s *Server) RunOldAppInitialization() error {
return store.NewTimerLayer(
localcachelayer.NewLocalCacheLayer(
sqlstore.NewSqlSupplier(s.FakeApp().Config().SqlSettings, s.Metrics),
s.Metrics, s.Cluster),
s.Metrics, s.Cluster, s.CacheProvider),
s.Metrics)
}
}

Просмотреть файл

@@ -6,17 +6,10 @@ package app
import (
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/utils"
)
var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE)
func ClearStatusCache() {
statusCache.Purge()
}
func (a *App) AddStatusCacheSkipClusterSend(status *model.Status) {
statusCache.Add(status.UserId, status)
a.Srv.statusCache.Add(status.UserId, status)
}
func (a *App) AddStatusCache(status *model.Status) {
@@ -37,12 +30,12 @@ func (a *App) GetAllStatuses() map[string]*model.Status {
return map[string]*model.Status{}
}
userIds := statusCache.Keys()
userIds := a.Srv.statusCache.Keys()
statusMap := map[string]*model.Status{}
for _, userId := range userIds {
if id, ok := userId.(string); ok {
status := GetStatusFromCache(id)
status := a.GetStatusFromCache(id)
if status != nil {
statusMap[id] = status
}
@@ -62,7 +55,7 @@ func (a *App) GetStatusesByIds(userIds []string) (map[string]interface{}, *model
missingUserIds := []string{}
for _, userId := range userIds {
if result, ok := statusCache.Get(userId); ok {
if result, ok := a.Srv.statusCache.Get(userId); ok {
statusMap[userId] = result.(*model.Status).Status
if metrics != nil {
metrics.IncrementMemCacheHitCounter("Status")
@@ -109,7 +102,7 @@ func (a *App) GetUserStatusesByIds(userIds []string) ([]*model.Status, *model.Ap
missingUserIds := []string{}
for _, userId := range userIds {
if result, ok := statusCache.Get(userId); ok {
if result, ok := a.Srv.statusCache.Get(userId); ok {
statusMap = append(statusMap, result.(*model.Status))
if metrics != nil {
metrics.IncrementMemCacheHitCounter("Status")
@@ -329,8 +322,8 @@ func (a *App) SetStatusOutOfOffice(userId string) {
a.SaveAndBroadcastStatus(status)
}
func GetStatusFromCache(userId string) *model.Status {
if result, ok := statusCache.Get(userId); ok {
func (a *App) GetStatusFromCache(userId string) *model.Status {
if result, ok := a.Srv.statusCache.Get(userId); ok {
status := result.(*model.Status)
statusCopy := &model.Status{}
*statusCopy = *status
@@ -345,7 +338,7 @@ func (a *App) GetStatus(userId string) (*model.Status, *model.AppError) {
return &model.Status{}, nil
}
status := GetStatusFromCache(userId)
status := a.GetStatusFromCache(userId)
if status != nil {
return status, nil
}

2
go.mod
Просмотреть файл

@@ -58,8 +58,6 @@ require (
github.com/muesli/smartcrop v0.3.0 // indirect
github.com/olekukonko/tablewriter v0.0.1 // indirect
github.com/olivere/elastic v6.2.23+incompatible // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect
github.com/pborman/uuid v1.2.0
github.com/pelletier/go-toml v1.4.0 // indirect
github.com/pkg/errors v0.8.1

60
services/cache/cache.go поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,60 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package cache
import (
"time"
)
// Cache is a representation of any cache store that has keys and values
type Cache interface {
// Purge is used to completely clear the cache.
Purge()
// Add adds the given key and value to the store without an expiry.
Add(key, value interface{})
// AddWithDefaultExpires adds the given key and value to the store with the default expiry.
AddWithDefaultExpires(key, value interface{})
// AddWithExpiresInSecs adds the given key and value to the cache with the given expiry.
AddWithExpiresInSecs(key, value interface{}, expireAtSecs int64)
// Get returns the value stored in the cache for a key, or nil if no value is present. The ok result indicates whether value was found in the cache.
Get(key interface{}) (value interface{}, ok bool)
// GetOrAdd returns the existing value for the key if present. Otherwise, it stores and returns the given value. The loaded result is true if the value was loaded, false if stored.
// This API intentionally deviates from the Add-only variants above for simplicity. We should simplify the entire API in the future.
GetOrAdd(key, value interface{}, ttl time.Duration) (actual interface{}, loaded bool)
// Remove deletes the value for a key.
Remove(key interface{})
// Keys returns a slice of the keys in the cache.
Keys() []interface{}
// Len returns the number of items in the cache.
Len() int
// Name identifies this cache instance among others in the system.
Name() string
// GetInvalidateClusterEvent returns the cluster event configured when this cache was created.
GetInvalidateClusterEvent() string
}
// Provider defines how to create new caches
type Provider interface {
// Connect opens a new connection to the cache using specific provider parameters.
Connect()
// NewCache creates a new cache with given size.
NewCache(size int) Cache
// NewCacheWithParams creates a new cache with the given parameters.
NewCacheWithParams(size int, name string, defaultExpiry int64, invalidateClusterEvent string) Cache
// Close releases any resources used by the cache provider.
Close()
}

37
utils/lru.go → services/cache/lru/lru.go поставляемый
Просмотреть файл

@@ -8,12 +8,14 @@
// LRU implementation in groupcache:
// https://github.com/golang/groupcache/tree/master/lru
package utils
package lru
import (
"container/list"
"sync"
"time"
"github.com/mattermost/mattermost-server/v5/services/cache"
)
// Cache is a thread-safe fixed size LRU cache.
@@ -29,6 +31,29 @@ type Cache struct {
len int
}
// CacheProvider is an implementation of cache.Provider to create a new Lru Cache
type CacheProvider struct{}
// NewCache creates a new lru.Cache with given size.
func (c *CacheProvider) NewCache(size int) cache.Cache {
return New(size)
}
// NewCacheWithParams creates a new lru.Cache with the given parameters.
func (c *CacheProvider) NewCacheWithParams(size int, name string, defaultExpiry int64, invalidateClusterEvent string) cache.Cache {
return NewWithParams(size, name, defaultExpiry, invalidateClusterEvent)
}
// Connect opens a new connection to the cache using specific provider parameters.
func (c *CacheProvider) Connect() {
}
// Close releases any resources used by the cache provider.
func (c *CacheProvider) Close() {
}
// entry is used to hold a value in the evictList.
type entry struct {
key interface{}
@@ -38,7 +63,7 @@ type entry struct {
}
// New creates an LRU of the given size.
func NewLru(size int) *Cache {
func New(size int) *Cache {
return &Cache{
size: size,
evictList: list.New(),
@@ -46,9 +71,9 @@ func NewLru(size int) *Cache {
}
}
// New creates an LRU with the given parameters.
func NewLruWithParams(size int, name string, defaultExpiry int64, invalidateClusterEvent string) *Cache {
lru := NewLru(size)
// NewWithParams creates an LRU with the given parameters.
func NewWithParams(size int, name string, defaultExpiry int64, invalidateClusterEvent string) *Cache {
lru := New(size)
lru.name = name
lru.defaultExpiry = defaultExpiry
lru.invalidateClusterEvent = invalidateClusterEvent
@@ -69,7 +94,7 @@ func (c *Cache) Add(key, value interface{}) {
c.AddWithExpiresInSecs(key, value, 0)
}
// Add adds the given key and value to the store with the default expiry.
// AddWithDefaultExpires adds the given key and value to the store with the default expiry.
func (c *Cache) AddWithDefaultExpires(key, value interface{}) {
c.AddWithExpiresInSecs(key, value, c.defaultExpiry)
}

Просмотреть файл

@@ -8,7 +8,7 @@
// LRU implementation in groupcache:
// https://github.com/golang/groupcache/tree/master/lru
package utils
package lru
import (
"testing"
@@ -19,7 +19,7 @@ import (
)
func TestLRU(t *testing.T) {
l := NewLru(128)
l := New(128)
for i := 0; i < 256; i++ {
l.Add(i, i)
@@ -60,7 +60,7 @@ func TestLRU(t *testing.T) {
}
func TestLRUExpire(t *testing.T) {
l := NewLru(128)
l := New(128)
l.AddWithExpiresInSecs(1, 1, 1)
l.AddWithExpiresInSecs(2, 2, 1)
@@ -76,7 +76,7 @@ func TestLRUExpire(t *testing.T) {
}
func TestLRUGetOrAdd(t *testing.T) {
l := NewLru(128)
l := New(128)
// First GetOrAdd should save
value, loaded := l.GetOrAdd(1, 1, 0)

Просмотреть файл

@@ -23,7 +23,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
count, err := cachedStore.Channel().GetMemberCount("id", true)
require.Nil(t, err)
@@ -37,7 +38,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetMemberCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
@@ -47,7 +49,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
t.Run("first call force not cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetMemberCount("id", false)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
@@ -59,7 +62,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
t.Run("first call with GetMemberCountFromCache not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
count := cachedStore.Channel().GetMemberCountFromCache("id")
assert.Equal(t, count, countResult)
@@ -71,7 +75,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetMemberCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
@@ -82,7 +87,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetMemberCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
@@ -97,7 +103,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
count, err := cachedStore.Channel().GetPinnedPostCount("id", true)
require.Nil(t, err)
@@ -111,7 +118,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetPinnedPostCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
@@ -121,7 +129,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
t.Run("first call force not cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetPinnedPostCount("id", false)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
@@ -133,7 +142,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetPinnedPostCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
@@ -144,7 +154,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetPinnedPostCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
@@ -159,7 +170,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
count, err := cachedStore.Channel().GetGuestCount("id", true)
require.Nil(t, err)
@@ -173,7 +185,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetGuestCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
@@ -183,7 +196,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
t.Run("first call force not cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetGuestCount("id", false)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
@@ -195,7 +209,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetGuestCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
@@ -206,7 +221,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().GetGuestCount("id", true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
@@ -221,7 +237,8 @@ func TestChannelStoreChannel(t *testing.T) {
fakeChannel := model.Channel{Id: channelId}
t.Run("first call by id not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
channel, err := cachedStore.Channel().Get(channelId, true)
require.Nil(t, err)
@@ -235,7 +252,8 @@ func TestChannelStoreChannel(t *testing.T) {
t.Run("first call not cached, second force no cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().Get(channelId, true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
@@ -245,7 +263,8 @@ func TestChannelStoreChannel(t *testing.T) {
t.Run("first call force no cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().Get(channelId, false)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
cachedStore.Channel().Get(channelId, true)
@@ -256,7 +275,8 @@ func TestChannelStoreChannel(t *testing.T) {
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().Get(channelId, true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
@@ -267,7 +287,8 @@ func TestChannelStoreChannel(t *testing.T) {
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Channel().Get(channelId, true)
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
cachedStore.Channel().InvalidateChannel(channelId)

Просмотреть файл

@@ -22,7 +22,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by id not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
emoji, err := cachedStore.Emoji().Get("123", true)
require.Nil(t, err)
@@ -36,7 +37,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by name not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
emoji, err := cachedStore.Emoji().GetByName("name123", true)
require.Nil(t, err)
@@ -50,7 +52,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by id not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().Get("123", true)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
@@ -60,7 +63,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by name not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().GetByName("name123", true)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
@@ -70,7 +74,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by id force not cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().Get("123", false)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
@@ -82,7 +87,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by name force not cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().GetByName("name123", false)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
@@ -94,7 +100,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by id, second call by name cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().Get("123", true)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
@@ -104,7 +111,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by name, second call by id cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().GetByName("name123", true)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
@@ -114,7 +122,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by id not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().Get("123", true)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
@@ -125,7 +134,8 @@ func TestEmojiStoreCache(t *testing.T) {
t.Run("first call by name not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Emoji().GetByName("name123", true)
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)

Просмотреть файл

@@ -6,8 +6,8 @@ package localcachelayer
import (
"github.com/mattermost/mattermost-server/v5/einterfaces"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/utils"
)
const (
@@ -56,65 +56,74 @@ const (
type LocalCacheStore struct {
store.Store
metrics einterfaces.MetricsInterface
cluster einterfaces.ClusterInterface
reaction LocalCacheReactionStore
reactionCache *utils.Cache
role LocalCacheRoleStore
roleCache *utils.Cache
scheme LocalCacheSchemeStore
schemeCache *utils.Cache
emoji LocalCacheEmojiStore
emojiCacheById *utils.Cache
emojiIdCacheByName *utils.Cache
channel LocalCacheChannelStore
channelMemberCountsCache *utils.Cache
channelGuestCountCache *utils.Cache
channelPinnedPostCountsCache *utils.Cache
channelByIdCache *utils.Cache
webhook LocalCacheWebhookStore
webhookCache *utils.Cache
post LocalCachePostStore
postLastPostsCache *utils.Cache
lastPostTimeCache *utils.Cache
user LocalCacheUserStore
userProfileByIdsCache *utils.Cache
team LocalCacheTeamStore
teamAllTeamIdsForUserCache *utils.Cache
termsOfService LocalCacheTermsOfServiceStore
termsOfServiceCache *utils.Cache
metrics einterfaces.MetricsInterface
cluster einterfaces.ClusterInterface
reaction LocalCacheReactionStore
reactionCache cache.Cache
role LocalCacheRoleStore
roleCache cache.Cache
scheme LocalCacheSchemeStore
schemeCache cache.Cache
emoji LocalCacheEmojiStore
emojiCacheById cache.Cache
emojiIdCacheByName cache.Cache
channel LocalCacheChannelStore
channelMemberCountsCache cache.Cache
channelGuestCountCache cache.Cache
channelPinnedPostCountsCache cache.Cache
channelByIdCache cache.Cache
webhook LocalCacheWebhookStore
webhookCache cache.Cache
post LocalCachePostStore
postLastPostsCache cache.Cache
lastPostTimeCache cache.Cache
user LocalCacheUserStore
userProfileByIdsCache cache.Cache
team LocalCacheTeamStore
teamAllTeamIdsForUserCache cache.Cache
termsOfService LocalCacheTermsOfServiceStore
termsOfServiceCache cache.Cache
}
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface) LocalCacheStore {
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider) LocalCacheStore {
localCacheStore := LocalCacheStore{
Store: baseStore,
cluster: cluster,
metrics: metrics,
}
localCacheStore.reactionCache = utils.NewLruWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS)
localCacheStore.reactionCache = cacheProvider.NewCacheWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS)
localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
localCacheStore.roleCache = utils.NewLruWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES)
localCacheStore.roleCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES)
localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
localCacheStore.schemeCache = utils.NewLruWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES)
localCacheStore.schemeCache = cacheProvider.NewCacheWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES)
localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
localCacheStore.webhookCache = utils.NewLruWithParams(WEBHOOK_CACHE_SIZE, "Webhook", WEBHOOK_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS)
localCacheStore.webhookCache = cacheProvider.NewCacheWithParams(WEBHOOK_CACHE_SIZE, "Webhook", WEBHOOK_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS)
localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
localCacheStore.emojiCacheById = utils.NewLruWithParams(EMOJI_CACHE_SIZE, "EmojiById", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID)
localCacheStore.emojiIdCacheByName = utils.NewLruWithParams(EMOJI_CACHE_SIZE, "EmojiByName", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME)
localCacheStore.emojiCacheById = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiById", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID)
localCacheStore.emojiIdCacheByName = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiByName", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME)
localCacheStore.emoji = LocalCacheEmojiStore{EmojiStore: baseStore.Emoji(), rootStore: &localCacheStore}
localCacheStore.channelPinnedPostCountsCache = utils.NewLruWithParams(CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SIZE, "ChannelPinnedPostsCounts", CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_PINNEDPOSTS_COUNTS)
localCacheStore.channelMemberCountsCache = utils.NewLruWithParams(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE, "ChannelMemberCounts", CHANNEL_MEMBERS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS)
localCacheStore.channelGuestCountCache = utils.NewLruWithParams(CHANNEL_GUEST_COUNT_CACHE_SIZE, "ChannelGuestsCount", CHANNEL_GUEST_COUNT_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT)
localCacheStore.channelByIdCache = utils.NewLruWithParams(model.CHANNEL_CACHE_SIZE, "channelById", CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL)
localCacheStore.channelPinnedPostCountsCache = cacheProvider.NewCacheWithParams(CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SIZE, "ChannelPinnedPostsCounts", CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_PINNEDPOSTS_COUNTS)
localCacheStore.channelMemberCountsCache = cacheProvider.NewCacheWithParams(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE, "ChannelMemberCounts", CHANNEL_MEMBERS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS)
localCacheStore.channelGuestCountCache = cacheProvider.NewCacheWithParams(CHANNEL_GUEST_COUNT_CACHE_SIZE, "ChannelGuestsCount", CHANNEL_GUEST_COUNT_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT)
localCacheStore.channelByIdCache = cacheProvider.NewCacheWithParams(model.CHANNEL_CACHE_SIZE, "channelById", CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL)
localCacheStore.channel = LocalCacheChannelStore{ChannelStore: baseStore.Channel(), rootStore: &localCacheStore}
localCacheStore.lastPostTimeCache = utils.NewLruWithParams(LAST_POST_TIME_CACHE_SIZE, "LastPostTime", LAST_POST_TIME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME)
localCacheStore.postLastPostsCache = utils.NewLruWithParams(LAST_POSTS_CACHE_SIZE, "LastPost", LAST_POSTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS)
localCacheStore.postLastPostsCache = cacheProvider.NewCacheWithParams(LAST_POSTS_CACHE_SIZE, "LastPost", LAST_POSTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS)
localCacheStore.lastPostTimeCache = cacheProvider.NewCacheWithParams(LAST_POST_TIME_CACHE_SIZE, "LastPostTime", LAST_POST_TIME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME)
localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
localCacheStore.termsOfServiceCache = utils.NewLruWithParams(TERMS_OF_SERVICE_CACHE_SIZE, "TermsOfService", TERMS_OF_SERVICE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE)
localCacheStore.termsOfServiceCache = cacheProvider.NewCacheWithParams(TERMS_OF_SERVICE_CACHE_SIZE, "TermsOfService", TERMS_OF_SERVICE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE)
localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
localCacheStore.userProfileByIdsCache = utils.NewLruWithParams(USER_PROFILE_BY_ID_CACHE_SIZE, "UserProfileByIds", USER_PROFILE_BY_ID_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS)
localCacheStore.userProfileByIdsCache = cacheProvider.NewCacheWithParams(USER_PROFILE_BY_ID_CACHE_SIZE, "UserProfileByIds", USER_PROFILE_BY_ID_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS)
localCacheStore.user = LocalCacheUserStore{UserStore: baseStore.User(), rootStore: &localCacheStore}
localCacheStore.teamAllTeamIdsForUserCache = utils.NewLruWithParams(TEAM_CACHE_SIZE, "Team", TEAM_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS)
localCacheStore.teamAllTeamIdsForUserCache = cacheProvider.NewCacheWithParams(TEAM_CACHE_SIZE, "Team", TEAM_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS)
localCacheStore.team = LocalCacheTeamStore{TeamStore: baseStore.Team(), rootStore: &localCacheStore}
if cluster != nil {
@@ -182,7 +191,7 @@ func (s LocalCacheStore) DropAllTables() {
s.Store.DropAllTables()
}
func (s *LocalCacheStore) doInvalidateCacheCluster(cache *utils.Cache, key string) {
func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache.Cache, key string) {
cache.Remove(key)
if s.cluster != nil {
msg := &model.ClusterMessage{
@@ -194,11 +203,11 @@ func (s *LocalCacheStore) doInvalidateCacheCluster(cache *utils.Cache, key strin
}
}
func (s *LocalCacheStore) doStandardAddToCache(cache *utils.Cache, key string, value interface{}) {
func (s *LocalCacheStore) doStandardAddToCache(cache cache.Cache, key string, value interface{}) {
cache.AddWithDefaultExpires(key, value)
}
func (s *LocalCacheStore) doStandardReadCache(cache *utils.Cache, key string) interface{} {
func (s *LocalCacheStore) doStandardReadCache(cache cache.Cache, key string) interface{} {
if cacheItem, ok := cache.Get(key); ok {
if s.metrics != nil {
s.metrics.IncrementMemCacheHitCounter(cache.Name())
@@ -213,7 +222,7 @@ func (s *LocalCacheStore) doStandardReadCache(cache *utils.Cache, key string) in
return nil
}
func (s *LocalCacheStore) doClearCacheCluster(cache *utils.Cache) {
func (s *LocalCacheStore) doClearCacheCluster(cache cache.Cache) {
cache.Purge()
if s.cluster != nil {
msg := &model.ClusterMessage{

Просмотреть файл

@@ -71,7 +71,7 @@ func initStores() {
go func() {
defer wg.Done()
st.SqlSupplier = sqlstore.NewSqlSupplier(*st.SqlSettings, nil)
st.Store = NewLocalCacheLayer(st.SqlSupplier, nil, nil)
st.Store = NewLocalCacheLayer(st.SqlSupplier, nil, nil, getMockCacheProvider())
st.Store.DropAllTables()
st.Store.MarkSystemRanUnitTests()
}()

Просмотреть файл

@@ -8,13 +8,29 @@ import (
"testing"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
"github.com/mattermost/mattermost-server/v5/testlib"
"github.com/stretchr/testify/mock"
)
var mainHelper *testlib.MainHelper
func getMockCacheProvider() *mocks.CacheProvider {
mockCacheProvider := mocks.CacheProvider{}
//todo: replace this line with mocks for all tests
mockCache := lru.New(128)
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
mock.AnythingOfType("string"),
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(mockCache)
return &mockCacheProvider
}
func getMockStore() *mocks.Store {
mockStore := mocks.Store{}

Просмотреть файл

@@ -29,7 +29,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetEtag: first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
expectedResult := fmt.Sprintf("%v.%v", model.CurrentVersion, fakeLastTime)
@@ -44,7 +45,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetEtag: first call not cached, second force no cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Post().GetEtag(channelId, true)
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetEtag", 1)
@@ -54,7 +56,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetEtag: first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Post().GetEtag(channelId, true)
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetEtag", 1)
@@ -65,7 +68,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetEtag: first call not cached, clear caches, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Post().GetEtag(channelId, true)
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetEtag", 1)
@@ -76,7 +80,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetPostsSince: first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
expectedResult := model.NewPostList()
@@ -93,7 +98,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetPostsSince: first call not cached, second force no cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Post().GetPostsSince(fakeOptions, true)
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetPostsSince", 1)
@@ -103,7 +109,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetPostsSince: first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Post().GetPostsSince(fakeOptions, true)
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetPostsSince", 1)
@@ -114,7 +121,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
t.Run("GetPostsSince: first call not cached, clear caches, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Post().GetPostsSince(fakeOptions, true)
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetPostsSince", 1)
@@ -130,7 +138,8 @@ func TestPostStoreCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotPosts, err := cachedStore.Post().GetPosts(fakeOptions, true)
require.Nil(t, err)
@@ -143,7 +152,8 @@ func TestPostStoreCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotPosts, err := cachedStore.Post().GetPosts(fakeOptions, true)
require.Nil(t, err)
@@ -156,7 +166,8 @@ func TestPostStoreCache(t *testing.T) {
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotPosts, err := cachedStore.Post().GetPosts(fakeOptions, true)
require.Nil(t, err)

Просмотреть файл

@@ -22,7 +22,8 @@ func TestReactionStoreCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
reaction, err := cachedStore.Reaction().GetForPost("123", true)
require.Nil(t, err)
@@ -36,7 +37,8 @@ func TestReactionStoreCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Reaction().GetForPost("123", true)
mockStore.Reaction().(*mocks.ReactionStore).AssertNumberOfCalls(t, "GetForPost", 1)
@@ -46,7 +48,8 @@ func TestReactionStoreCache(t *testing.T) {
t.Run("first call not cached, save, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Reaction().GetForPost("123", true)
mockStore.Reaction().(*mocks.ReactionStore).AssertNumberOfCalls(t, "GetForPost", 1)
@@ -57,7 +60,8 @@ func TestReactionStoreCache(t *testing.T) {
t.Run("first call not cached, delete, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Reaction().GetForPost("123", true)
mockStore.Reaction().(*mocks.ReactionStore).AssertNumberOfCalls(t, "GetForPost", 1)

Просмотреть файл

@@ -22,7 +22,8 @@ func TestRoleStoreCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
role, err := cachedStore.Role().GetByName("role-name")
require.Nil(t, err)
@@ -36,7 +37,8 @@ func TestRoleStoreCache(t *testing.T) {
t.Run("first call not cached, save, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Role().GetByName("role-name")
mockStore.Role().(*mocks.RoleStore).AssertNumberOfCalls(t, "GetByName", 1)
@@ -47,7 +49,8 @@ func TestRoleStoreCache(t *testing.T) {
t.Run("first call not cached, delete, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Role().GetByName("role-name")
mockStore.Role().(*mocks.RoleStore).AssertNumberOfCalls(t, "GetByName", 1)
@@ -58,7 +61,8 @@ func TestRoleStoreCache(t *testing.T) {
t.Run("first call not cached, permanent delete all, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Role().GetByName("role-name")
mockStore.Role().(*mocks.RoleStore).AssertNumberOfCalls(t, "GetByName", 1)

Просмотреть файл

@@ -22,7 +22,8 @@ func TestSchemeStoreCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
scheme, err := cachedStore.Scheme().Get("123")
require.Nil(t, err)
@@ -36,7 +37,8 @@ func TestSchemeStoreCache(t *testing.T) {
t.Run("first call not cached, save, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Scheme().Get("123")
mockStore.Scheme().(*mocks.SchemeStore).AssertNumberOfCalls(t, "Get", 1)
@@ -47,7 +49,8 @@ func TestSchemeStoreCache(t *testing.T) {
t.Run("first call not cached, delete, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Scheme().Get("123")
mockStore.Scheme().(*mocks.SchemeStore).AssertNumberOfCalls(t, "Get", 1)
@@ -58,7 +61,8 @@ func TestSchemeStoreCache(t *testing.T) {
t.Run("first call not cached, permanent delete all, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Scheme().Get("123")
mockStore.Scheme().(*mocks.SchemeStore).AssertNumberOfCalls(t, "Get", 1)

Просмотреть файл

@@ -22,7 +22,8 @@ func TestTeamStoreCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUserTeamIds, err := cachedStore.Team().GetUserTeamIds(fakeUserId, true)
require.Nil(t, err)
@@ -37,7 +38,8 @@ func TestTeamStoreCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUserTeamIds, err := cachedStore.Team().GetUserTeamIds(fakeUserId, true)
require.Nil(t, err)
@@ -52,7 +54,8 @@ func TestTeamStoreCache(t *testing.T) {
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUserTeamIds, err := cachedStore.Team().GetUserTeamIds(fakeUserId, true)
require.Nil(t, err)

Просмотреть файл

@@ -23,7 +23,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call by latest not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
termsOfService, err := cachedStore.TermsOfService().GetLatest(true)
require.Nil(t, err)
@@ -37,7 +38,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call by id not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
termsOfService, err := cachedStore.TermsOfService().Get("123", true)
require.Nil(t, err)
@@ -51,7 +53,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call by id not cached, second force no cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().Get("123", true)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "Get", 1)
@@ -61,7 +64,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call latest not cached, second force no cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().GetLatest(true)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
@@ -71,7 +75,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call by id force no cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().Get("123", false)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "Get", 1)
@@ -83,7 +88,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call latest force no cached, second not cached, third cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().GetLatest(false)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
@@ -95,7 +101,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call latest, second call by id cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().GetLatest(true)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
@@ -105,7 +112,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first call by id not cached, save, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().Get("123", false)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "Get", 1)
@@ -116,7 +124,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
t.Run("first get latest not cached, save new, then get latest, returning different data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.TermsOfService().GetLatest(true)
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)

Просмотреть файл

@@ -25,7 +25,8 @@ func TestUserStoreGetProfileByIdsCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUser, err := cachedStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, true)
require.Nil(t, err)
@@ -38,7 +39,8 @@ func TestUserStoreGetProfileByIdsCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUser, err := cachedStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, true)
require.Nil(t, err)
@@ -51,7 +53,8 @@ func TestUserStoreGetProfileByIdsCache(t *testing.T) {
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUser, err := cachedStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, true)
require.Nil(t, err)
@@ -71,7 +74,8 @@ func TestUserStoreGetCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUser, err := cachedStore.User().Get(fakeUserId)
require.Nil(t, err)
@@ -84,7 +88,8 @@ func TestUserStoreGetCache(t *testing.T) {
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
gotUser, err := cachedStore.User().Get(fakeUserId)
require.Nil(t, err)

Просмотреть файл

@@ -23,7 +23,8 @@ func TestWebhookStoreCache(t *testing.T) {
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
incomingWebhook, err := cachedStore.Webhook().GetIncoming("123", true)
require.Nil(t, err)
@@ -37,7 +38,8 @@ func TestWebhookStoreCache(t *testing.T) {
t.Run("first call not cached, second force not cached", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Webhook().GetIncoming("123", true)
mockStore.Webhook().(*mocks.WebhookStore).AssertNumberOfCalls(t, "GetIncoming", 1)
@@ -47,7 +49,8 @@ func TestWebhookStoreCache(t *testing.T) {
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
mockStore := getMockStore()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
mockCacheProvider := getMockCacheProvider()
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
cachedStore.Webhook().GetIncoming("123", true)
mockStore.Webhook().(*mocks.WebhookStore).AssertNumberOfCalls(t, "GetIncoming", 1)

Просмотреть файл

@@ -18,8 +18,8 @@ import (
"github.com/mattermost/mattermost-server/v5/einterfaces"
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/utils"
)
const (
@@ -274,9 +274,9 @@ type publicChannel struct {
Purpose string `json:"purpose"`
}
var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
var allChannelMembersNotifyPropsForChannelCache = utils.NewLru(ALL_CHANNEL_MEMBERS_NOTIFY_PROPS_FOR_CHANNEL_CACHE_SIZE)
var channelByNameCache = utils.NewLru(model.CHANNEL_CACHE_SIZE)
var allChannelMembersForUserCache = lru.New(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
var allChannelMembersNotifyPropsForChannelCache = lru.New(ALL_CHANNEL_MEMBERS_NOTIFY_PROPS_FOR_CHANNEL_CACHE_SIZE)
var channelByNameCache = lru.New(model.CHANNEL_CACHE_SIZE)
func (s SqlChannelStore) ClearCaches() {
allChannelMembersForUserCache.Purge()

Просмотреть файл

@@ -11,8 +11,9 @@ import (
"github.com/mattermost/mattermost-server/v5/einterfaces"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/utils"
)
type SqlFileInfoStore struct {
@@ -25,7 +26,7 @@ const (
FILE_INFO_CACHE_SEC = 1800 // 30 minutes
)
var fileInfoCache *utils.Cache = utils.NewLru(FILE_INFO_CACHE_SIZE)
var fileInfoCache cache.Cache = lru.New(FILE_INFO_CACHE_SIZE)
func (fs SqlFileInfoStore) ClearCaches() {
fileInfoCache.Purge()

Просмотреть файл

@@ -16,8 +16,9 @@ import (
"github.com/mattermost/mattermost-server/v5/einterfaces"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/utils"
)
const (
@@ -41,7 +42,7 @@ type SqlUserStore struct {
usersQuery sq.SelectBuilder
}
var profilesInChannelCache *utils.Cache = utils.NewLru(PROFILES_IN_CHANNEL_CACHE_SIZE)
var profilesInChannelCache cache.Cache = lru.New(PROFILES_IN_CHANNEL_CACHE_SIZE)
func (us SqlUserStore) ClearCaches() {
profilesInChannelCache.Purge()

145
store/storetest/mocks/Cache.go Обычный файл
Просмотреть файл

@@ -0,0 +1,145 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
// Regenerate this file using `make store-mocks`.
package mocks
import (
mock "github.com/stretchr/testify/mock"
time "time"
)
// Cache is an autogenerated mock type for the Cache type
type Cache struct {
mock.Mock
}
// Add provides a mock function with given fields: key, value
func (_m *Cache) Add(key interface{}, value interface{}) {
_m.Called(key, value)
}
// AddWithDefaultExpires provides a mock function with given fields: key, value
func (_m *Cache) AddWithDefaultExpires(key interface{}, value interface{}) {
_m.Called(key, value)
}
// AddWithExpiresInSecs provides a mock function with given fields: key, value, expireAtSecs
func (_m *Cache) AddWithExpiresInSecs(key interface{}, value interface{}, expireAtSecs int64) {
_m.Called(key, value, expireAtSecs)
}
// Get provides a mock function with given fields: key
func (_m *Cache) Get(key interface{}) (interface{}, bool) {
ret := _m.Called(key)
var r0 interface{}
if rf, ok := ret.Get(0).(func(interface{}) interface{}); ok {
r0 = rf(key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(interface{})
}
}
var r1 bool
if rf, ok := ret.Get(1).(func(interface{}) bool); ok {
r1 = rf(key)
} else {
r1 = ret.Get(1).(bool)
}
return r0, r1
}
// GetInvalidateClusterEvent provides a mock function with given fields:
func (_m *Cache) GetInvalidateClusterEvent() string {
ret := _m.Called()
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// GetOrAdd provides a mock function with given fields: key, value, ttl
func (_m *Cache) GetOrAdd(key interface{}, value interface{}, ttl time.Duration) (interface{}, bool) {
ret := _m.Called(key, value, ttl)
var r0 interface{}
if rf, ok := ret.Get(0).(func(interface{}, interface{}, time.Duration) interface{}); ok {
r0 = rf(key, value, ttl)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(interface{})
}
}
var r1 bool
if rf, ok := ret.Get(1).(func(interface{}, interface{}, time.Duration) bool); ok {
r1 = rf(key, value, ttl)
} else {
r1 = ret.Get(1).(bool)
}
return r0, r1
}
// Keys provides a mock function with given fields:
func (_m *Cache) Keys() []interface{} {
ret := _m.Called()
var r0 []interface{}
if rf, ok := ret.Get(0).(func() []interface{}); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]interface{})
}
}
return r0
}
// Len provides a mock function with given fields:
func (_m *Cache) Len() int {
ret := _m.Called()
var r0 int
if rf, ok := ret.Get(0).(func() int); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(int)
}
return r0
}
// Name provides a mock function with given fields:
func (_m *Cache) Name() string {
ret := _m.Called()
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// Purge provides a mock function with given fields:
func (_m *Cache) Purge() {
_m.Called()
}
// Remove provides a mock function with given fields: key
func (_m *Cache) Remove(key interface{}) {
_m.Called(key)
}

57
store/storetest/mocks/CacheProvider.go Обычный файл
Просмотреть файл

@@ -0,0 +1,57 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
// Regenerate this file using `make store-mocks`.
package mocks
import (
cache "github.com/mattermost/mattermost-server/v5/services/cache"
mock "github.com/stretchr/testify/mock"
)
// CacheProvider is an autogenerated mock type for the CacheProvider type
type CacheProvider struct {
mock.Mock
}
// NewCache provides a mock function with given fields: size
func (_m *CacheProvider) NewCache(size int) cache.Cache {
ret := _m.Called(size)
var r0 cache.Cache
if rf, ok := ret.Get(0).(func(int) cache.Cache); ok {
r0 = rf(size)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(cache.Cache)
}
}
return r0
}
// Connect provides a mock function with given fields:
func (_m *CacheProvider) Connect() {
_m.Called()
}
// Close provides a mock function with given fields:
func (_m *CacheProvider) Close() {
_m.Called()
}
// NewCacheWithParams provides a mock function with given fields: size, name, defaultExpiry, invalidateClusterEvent
func (_m *CacheProvider) NewCacheWithParams(size int, name string, defaultExpiry int64, invalidateClusterEvent string) cache.Cache {
ret := _m.Called(size, name, defaultExpiry, invalidateClusterEvent)
var r0 cache.Cache
if rf, ok := ret.Get(0).(func(int, string, int64, string) cache.Cache); ok {
r0 = rf(size, name, defaultExpiry, invalidateClusterEvent)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(cache.Cache)
}
}
return r0
}

Просмотреть файл

@@ -4,10 +4,9 @@
package storetest
import (
"github.com/stretchr/testify/mock"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
"github.com/stretchr/testify/mock"
)
// Store can be used to provide mock stores for testing.