MM-25115 - make cacheProvider2 accessible to localcachelayer (#14691)

* make cacheProvider2 accessible to localcachelayer

* migrate localcachelayer

* revert test.sh

* workaround gob deserialization issue

* fix web_test.go

* merge conflicts

* resolve merge conflicts

* revert back test workaround

* fix the wrong merge
Этот коммит содержится в:
Siyuan Liu
2020-06-25 04:38:53 -07:00
коммит произвёл GitHub
родитель 1648b11e82
Коммит aaea36a24d
27 изменённых файлов: 484 добавлений и 433 удалений

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

@@ -98,7 +98,7 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent
}
if includeCache {
// Adds the cache layer to the test store
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider)
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider2)
}
th := &TestHelper{

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

@@ -76,7 +76,7 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
if includeCacheLayer {
// Adds the cache layer to the test store
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider)
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider2)
}
th := &TestHelper{

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

@@ -320,7 +320,7 @@ func NewServer(options ...Option) (*Server, error) {
s.sqlStore,
s.Metrics,
s.Cluster,
s.CacheProvider,
s.CacheProvider2,
),
s.SearchEngine,
s.Config(),

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

@@ -47,7 +47,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
panic(err)
}
// Adds the cache layer to the test store
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider)
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider2)
th := &TestHelper{
App: app.New(app.ServerConnector(s)),

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

@@ -43,4 +43,7 @@ type Cache interface {
// GetInvalidateClusterEvent returns the cluster event configured when this cache was created.
GetInvalidateClusterEvent() string
// Name returns the name of the cache
Name() string
}

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

@@ -13,6 +13,7 @@ import (
// LRU is a thread-safe fixed size LRU cache.
type LRU struct {
name string
size int
evictList *list.List
items map[string]*list.Element
@@ -25,6 +26,7 @@ type LRU struct {
// LRUOptions contains options for initializing LRU cache
type LRUOptions struct {
Name string
Size int
DefaultExpiry time.Duration
InvalidateClusterEvent string
@@ -41,6 +43,7 @@ type entry struct {
// NewLRU creates an LRU of the given size.
func NewLRU(opts *LRUOptions) Cache {
return &LRU{
name: opts.Name,
size: opts.Size,
evictList: list.New(),
items: make(map[string]*list.Element, opts.Size),
@@ -127,6 +130,11 @@ func (l *LRU) GetInvalidateClusterEvent() string {
return l.invalidateClusterEvent
}
// Name returns the name of the cache
func (l *LRU) Name() string {
return l.name
}
func (l *LRU) set(key string, value interface{}, ttl time.Duration) error {
var expires time.Time
if ttl > 0 {

167
services/cache2/mocks/Cache.go Обычный файл
Просмотреть файл

@@ -0,0 +1,167 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
package mocks
import mock "github.com/stretchr/testify/mock"
import time "time"
// Cache is an autogenerated mock type for the Cache type
type Cache struct {
mock.Mock
}
// Get provides a mock function with given fields: key, value
func (_m *Cache) Get(key string, value interface{}) error {
ret := _m.Called(key, value)
var r0 error
if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
r0 = rf(key, value)
} else {
r0 = ret.Error(0)
}
return r0
}
// 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
}
// Keys provides a mock function with given fields:
func (_m *Cache) Keys() ([]string, error) {
ret := _m.Called()
var r0 []string
if rf, ok := ret.Get(0).(func() []string); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Len provides a mock function with given fields:
func (_m *Cache) Len() (int, error) {
ret := _m.Called()
var r0 int
if rf, ok := ret.Get(0).(func() int); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(int)
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// 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() error {
ret := _m.Called()
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// Remove provides a mock function with given fields: key
func (_m *Cache) Remove(key string) error {
ret := _m.Called(key)
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(key)
} else {
r0 = ret.Error(0)
}
return r0
}
// Set provides a mock function with given fields: key, value
func (_m *Cache) Set(key string, value interface{}) error {
ret := _m.Called(key, value)
var r0 error
if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
r0 = rf(key, value)
} else {
r0 = ret.Error(0)
}
return r0
}
// SetWithDefaultExpiry provides a mock function with given fields: key, value
func (_m *Cache) SetWithDefaultExpiry(key string, value interface{}) error {
ret := _m.Called(key, value)
var r0 error
if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
r0 = rf(key, value)
} else {
r0 = ret.Error(0)
}
return r0
}
// SetWithExpiry provides a mock function with given fields: key, value, ttl
func (_m *Cache) SetWithExpiry(key string, value interface{}, ttl time.Duration) error {
ret := _m.Called(key, value, ttl)
var r0 error
if rf, ok := ret.Get(0).(func(string, interface{}, time.Duration) error); ok {
r0 = rf(key, value, ttl)
} else {
r0 = ret.Error(0)
}
return r0
}

55
services/cache2/mocks/Provider.go Обычный файл
Просмотреть файл

@@ -0,0 +1,55 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
package mocks
import cache2 "github.com/mattermost/mattermost-server/v5/services/cache2"
import mock "github.com/stretchr/testify/mock"
// Provider is an autogenerated mock type for the Provider type
type Provider struct {
mock.Mock
}
// Close provides a mock function with given fields:
func (_m *Provider) Close() error {
ret := _m.Called()
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// Connect provides a mock function with given fields:
func (_m *Provider) Connect() error {
ret := _m.Called()
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// NewCache provides a mock function with given fields: opts
func (_m *Provider) NewCache(opts *cache2.CacheOptions) cache2.Cache {
ret := _m.Called(opts)
var r0 cache2.Cache
if rf, ok := ret.Get(0).(func(*cache2.CacheOptions) cache2.Cache); ok {
r0 = rf(opts)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(cache2.Cache)
}
}
return r0
}

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

@@ -34,6 +34,7 @@ func NewProvider() Provider {
// NewCache creates a new cache with given opts
func (c *cacheProvider) NewCache(opts *CacheOptions) Cache {
return NewLRU(&LRUOptions{
Name: opts.Name,
Size: opts.Size,
DefaultExpiry: opts.DefaultExpiry,
InvalidateClusterEvent: opts.InvalidateClusterEvent,

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

@@ -89,8 +89,9 @@ func (s LocalCacheChannelStore) InvalidateChannel(channelId string) {
func (s LocalCacheChannelStore) GetMemberCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
if allowFromCache {
if count := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId); count != nil {
return count.(int64), nil
var count int64
if err := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId, &count); err == nil {
return count, nil
}
}
count, err := s.ChannelStore.GetMemberCount(channelId, allowFromCache)
@@ -104,8 +105,9 @@ func (s LocalCacheChannelStore) GetMemberCount(channelId string, allowFromCache
func (s LocalCacheChannelStore) GetGuestCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
if allowFromCache {
if count := s.rootStore.doStandardReadCache(s.rootStore.channelGuestCountCache, channelId); count != nil {
return count.(int64), nil
var count int64
if err := s.rootStore.doStandardReadCache(s.rootStore.channelGuestCountCache, channelId, &count); err == nil {
return count, nil
}
}
count, err := s.ChannelStore.GetGuestCount(channelId, allowFromCache)
@@ -118,8 +120,9 @@ func (s LocalCacheChannelStore) GetGuestCount(channelId string, allowFromCache b
}
func (s LocalCacheChannelStore) GetMemberCountFromCache(channelId string) int64 {
if count := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId); count != nil {
return count.(int64)
var count int64
if err := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId, &count); err == nil {
return count
}
count, err := s.GetMemberCount(channelId, true)
@@ -132,8 +135,9 @@ func (s LocalCacheChannelStore) GetMemberCountFromCache(channelId string) int64
func (s LocalCacheChannelStore) GetPinnedPostCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
if allowFromCache {
if count := s.rootStore.doStandardReadCache(s.rootStore.channelPinnedPostCountsCache, channelId); count != nil {
return count.(int64), nil
var count int64
if err := s.rootStore.doStandardReadCache(s.rootStore.channelPinnedPostCountsCache, channelId, &count); err == nil {
return count, nil
}
}
@@ -153,8 +157,9 @@ func (s LocalCacheChannelStore) GetPinnedPostCount(channelId string, allowFromCa
func (s LocalCacheChannelStore) Get(id string, allowFromCache bool) (*model.Channel, error) {
if allowFromCache {
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.channelByIdCache, id); cacheItem != nil {
ch := cacheItem.(*model.Channel).DeepCopy()
var cacheItem *model.Channel
if err := s.rootStore.doStandardReadCache(s.rootStore.channelByIdCache, id, &cacheItem); err == nil {
ch := cacheItem.DeepCopy()
return ch, nil
}
}

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

@@ -4,9 +4,10 @@
package localcachelayer
import (
"github.com/mattermost/mattermost-server/v5/model"
"testing"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

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

@@ -81,15 +81,17 @@ func (es LocalCacheEmojiStore) addToCache(emoji *model.Emoji) {
}
func (es LocalCacheEmojiStore) getFromCacheById(id string) (*model.Emoji, bool) {
if emoji := es.rootStore.doStandardReadCache(es.rootStore.emojiCacheById, id); emoji != nil {
return emoji.(*model.Emoji), true
var emoji *model.Emoji
if err := es.rootStore.doStandardReadCache(es.rootStore.emojiCacheById, id, &emoji); err == nil {
return emoji, true
}
return nil, false
}
func (es LocalCacheEmojiStore) getFromCacheByName(name string) (*model.Emoji, bool) {
if emojiId := es.rootStore.doStandardReadCache(es.rootStore.emojiIdCacheByName, name); emojiId != nil {
return es.getFromCacheById(emojiId.(string))
var emojiId string
if err := es.rootStore.doStandardReadCache(es.rootStore.emojiIdCacheByName, name, &emojiId); err == nil {
return es.getFromCacheById(emojiId)
}
return nil, false
}

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

@@ -31,8 +31,9 @@ func (s LocalCacheFileInfoStore) GetForPost(postId string, readFromMaster, inclu
cacheKey += "_deleted"
}
if fileInfo := s.rootStore.doStandardReadCache(s.rootStore.fileInfoCache, cacheKey); fileInfo != nil {
return fileInfo.([]*model.FileInfo), nil
var fileInfo []*model.FileInfo
if err := s.rootStore.doStandardReadCache(s.rootStore.fileInfoCache, cacheKey, &fileInfo); err == nil {
return fileInfo, nil
}
fileInfos, err := s.FileInfoStore.GetForPost(postId, readFromMaster, includeDeleted, allowFromCache)

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

@@ -4,9 +4,11 @@
package localcachelayer
import (
"time"
"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/cache2"
"github.com/mattermost/mattermost-server/v5/store"
)
@@ -66,47 +68,47 @@ type LocalCacheStore struct {
cluster einterfaces.ClusterInterface
reaction LocalCacheReactionStore
reactionCache cache.Cache
reactionCache cache2.Cache
fileInfo LocalCacheFileInfoStore
fileInfoCache cache.Cache
fileInfoCache cache2.Cache
role LocalCacheRoleStore
roleCache cache.Cache
rolePermissionsCache cache.Cache
roleCache cache2.Cache
rolePermissionsCache cache2.Cache
scheme LocalCacheSchemeStore
schemeCache cache.Cache
schemeCache cache2.Cache
emoji LocalCacheEmojiStore
emojiCacheById cache.Cache
emojiIdCacheByName cache.Cache
emojiCacheById cache2.Cache
emojiIdCacheByName cache2.Cache
channel LocalCacheChannelStore
channelMemberCountsCache cache.Cache
channelGuestCountCache cache.Cache
channelPinnedPostCountsCache cache.Cache
channelByIdCache cache.Cache
channelMemberCountsCache cache2.Cache
channelGuestCountCache cache2.Cache
channelPinnedPostCountsCache cache2.Cache
channelByIdCache cache2.Cache
webhook LocalCacheWebhookStore
webhookCache cache.Cache
webhookCache cache2.Cache
post LocalCachePostStore
postLastPostsCache cache.Cache
lastPostTimeCache cache.Cache
postLastPostsCache cache2.Cache
lastPostTimeCache cache2.Cache
user LocalCacheUserStore
userProfileByIdsCache cache.Cache
profilesInChannelCache cache.Cache
userProfileByIdsCache cache2.Cache
profilesInChannelCache cache2.Cache
team LocalCacheTeamStore
teamAllTeamIdsForUserCache cache.Cache
teamAllTeamIdsForUserCache cache2.Cache
termsOfService LocalCacheTermsOfServiceStore
termsOfServiceCache cache.Cache
termsOfServiceCache cache2.Cache
}
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider) LocalCacheStore {
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache2.Provider) LocalCacheStore {
localCacheStore := LocalCacheStore{
Store: baseStore,
@@ -114,54 +116,144 @@ func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterf
metrics: metrics,
}
// Reactions
localCacheStore.reactionCache = cacheProvider.NewCacheWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS)
localCacheStore.reactionCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: REACTION_CACHE_SIZE,
Name: "Reaction",
DefaultExpiry: REACTION_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS,
})
localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
// Roles
localCacheStore.roleCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES)
localCacheStore.rolePermissionsCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "RolePermission", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS)
localCacheStore.roleCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: ROLE_CACHE_SIZE,
Name: "Role",
DefaultExpiry: ROLE_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES,
})
localCacheStore.rolePermissionsCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: ROLE_CACHE_SIZE,
Name: "RolePermission",
DefaultExpiry: ROLE_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS,
})
localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
// Schemes
localCacheStore.schemeCache = cacheProvider.NewCacheWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES)
localCacheStore.schemeCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: SCHEME_CACHE_SIZE,
Name: "Scheme",
DefaultExpiry: SCHEME_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES,
})
localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
// FileInfo
localCacheStore.fileInfoCache = cacheProvider.NewCacheWithParams(FILE_INFO_CACHE_SIZE, "FileInfo", FILE_INFO_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_FILE_INFOS)
localCacheStore.fileInfoCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: FILE_INFO_CACHE_SIZE,
Name: "FileInfo",
DefaultExpiry: FILE_INFO_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_FILE_INFOS,
})
localCacheStore.fileInfo = LocalCacheFileInfoStore{FileInfoStore: baseStore.FileInfo(), rootStore: &localCacheStore}
// Webhooks
localCacheStore.webhookCache = cacheProvider.NewCacheWithParams(WEBHOOK_CACHE_SIZE, "Webhook", WEBHOOK_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS)
localCacheStore.webhookCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: WEBHOOK_CACHE_SIZE,
Name: "Webhook",
DefaultExpiry: WEBHOOK_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS,
})
localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
// Emojis
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.emojiCacheById = cacheProvider.NewCache(&cache2.CacheOptions{
Size: EMOJI_CACHE_SIZE,
Name: "EmojiById",
DefaultExpiry: EMOJI_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID,
})
localCacheStore.emojiIdCacheByName = cacheProvider.NewCache(&cache2.CacheOptions{
Size: EMOJI_CACHE_SIZE,
Name: "EmojiByName",
DefaultExpiry: EMOJI_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME,
})
localCacheStore.emoji = LocalCacheEmojiStore{EmojiStore: baseStore.Emoji(), rootStore: &localCacheStore}
// Channels
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.channelPinnedPostCountsCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SIZE,
Name: "ChannelPinnedPostsCounts",
DefaultExpiry: CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_PINNEDPOSTS_COUNTS,
})
localCacheStore.channelMemberCountsCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: CHANNEL_MEMBERS_COUNTS_CACHE_SIZE,
Name: "ChannelMemberCounts",
DefaultExpiry: CHANNEL_MEMBERS_COUNTS_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS,
})
localCacheStore.channelGuestCountCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: CHANNEL_GUEST_COUNT_CACHE_SIZE,
Name: "ChannelGuestsCount",
DefaultExpiry: CHANNEL_GUEST_COUNT_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT,
})
localCacheStore.channelByIdCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: model.CHANNEL_CACHE_SIZE,
Name: "channelById",
DefaultExpiry: CHANNEL_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL,
})
localCacheStore.channel = LocalCacheChannelStore{ChannelStore: baseStore.Channel(), rootStore: &localCacheStore}
// 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.postLastPostsCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: LAST_POSTS_CACHE_SIZE,
Name: "LastPost",
DefaultExpiry: LAST_POSTS_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS,
})
localCacheStore.lastPostTimeCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: LAST_POST_TIME_CACHE_SIZE,
Name: "LastPostTime",
DefaultExpiry: LAST_POST_TIME_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME,
})
localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
// TOS
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.termsOfServiceCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: TERMS_OF_SERVICE_CACHE_SIZE,
Name: "TermsOfService",
DefaultExpiry: TERMS_OF_SERVICE_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE,
})
localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
// Users
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.profilesInChannelCache = cacheProvider.NewCacheWithParams(PROFILES_IN_CHANNEL_CACHE_SIZE, "ProfilesInChannel", PROFILES_IN_CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL)
localCacheStore.userProfileByIdsCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: USER_PROFILE_BY_ID_CACHE_SIZE,
Name: "UserProfileByIds",
DefaultExpiry: USER_PROFILE_BY_ID_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS,
})
localCacheStore.profilesInChannelCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: PROFILES_IN_CHANNEL_CACHE_SIZE,
Name: "ProfilesInChannel",
DefaultExpiry: PROFILES_IN_CHANNEL_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL,
})
localCacheStore.user = LocalCacheUserStore{UserStore: baseStore.User(), rootStore: &localCacheStore}
// Teams
localCacheStore.teamAllTeamIdsForUserCache = cacheProvider.NewCacheWithParams(TEAM_CACHE_SIZE, "Team", TEAM_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS)
localCacheStore.teamAllTeamIdsForUserCache = cacheProvider.NewCache(&cache2.CacheOptions{
Size: TEAM_CACHE_SIZE,
Name: "Team",
DefaultExpiry: TEAM_CACHE_SEC * time.Second,
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS,
})
localCacheStore.team = LocalCacheTeamStore{TeamStore: baseStore.Team(), rootStore: &localCacheStore}
if cluster != nil {
@@ -236,7 +328,7 @@ func (s LocalCacheStore) DropAllTables() {
s.Store.DropAllTables()
}
func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache.Cache, key string) {
func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache2.Cache, key string) {
cache.Remove(key)
if s.cluster != nil {
msg := &model.ClusterMessage{
@@ -248,26 +340,25 @@ func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache.Cache, key string
}
}
func (s *LocalCacheStore) doStandardAddToCache(cache cache.Cache, key string, value interface{}) {
cache.AddWithDefaultExpires(key, value)
func (s *LocalCacheStore) doStandardAddToCache(cache cache2.Cache, key string, value interface{}) {
cache.SetWithDefaultExpiry(key, value)
}
func (s *LocalCacheStore) doStandardReadCache(cache cache.Cache, key string) interface{} {
if cacheItem, ok := cache.Get(key); ok {
func (s *LocalCacheStore) doStandardReadCache(cache cache2.Cache, key string, value interface{}) error {
if err := cache.Get(key, value); err == nil {
if s.metrics != nil {
s.metrics.IncrementMemCacheHitCounter(cache.Name())
}
return cacheItem
return nil
} else {
if s.metrics != nil {
s.metrics.IncrementMemCacheMissCounter(cache.Name())
}
return err
}
if s.metrics != nil {
s.metrics.IncrementMemCacheMissCounter(cache.Name())
}
return nil
}
func (s *LocalCacheStore) doClearCacheCluster(cache cache.Cache) {
func (s *LocalCacheStore) doClearCacheCluster(cache cache2.Cache) {
cache.Purge()
if s.cluster != nil {
msg := &model.ClusterMessage{

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

@@ -7,8 +7,10 @@ import (
"fmt"
"testing"
"github.com/mattermost/mattermost-server/v5/services/cache2"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/cache/lru"
cachemocks "github.com/mattermost/mattermost-server/v5/services/cache2/mocks"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
"github.com/mattermost/mattermost-server/v5/testlib"
@@ -17,117 +19,10 @@ import (
var mainHelper *testlib.MainHelper
func getMockCacheProvider() *mocks.CacheProvider {
mockCacheProvider := mocks.CacheProvider{}
//todo: replace this line with mocks for all tests
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"Reaction",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"Role",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"RolePermission",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"Scheme",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"Webhook",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"EmojiById",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"EmojiByName",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"ChannelPinnedPostsCounts",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"ChannelMemberCounts",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"ChannelGuestsCount",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"channelById",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"LastPost",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"LastPostTime",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"TermsOfService",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"UserProfileByIds",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"ProfilesInChannel",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"Team",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
mockCacheProvider.On("NewCacheWithParams",
mock.AnythingOfType("int"),
"FileInfo",
mock.AnythingOfType("int64"),
mock.AnythingOfType("string")).Return(lru.New(128))
func getMockCacheProvider() cache2.Provider {
mockCacheProvider := cachemocks.Provider{}
mockCacheProvider.On("NewCache", mock.Anything).
Return(cache2.NewLRU(&cache2.LRUOptions{Size: 128}))
return &mockCacheProvider
}
@@ -230,7 +125,11 @@ func getMockStore() *mocks.Store {
mockTermsOfServiceStore.On("Get", "123", false).Return(&fakeTermsOfService, nil)
mockStore.On("TermsOfService").Return(&mockTermsOfServiceStore)
fakeUser := []*model.User{{Id: "123", AuthData: model.NewString("")}}
fakeUser := []*model.User{{
Id: "123",
AuthData: model.NewString("authData"),
AuthService: "authService",
}}
mockUserStore := mocks.UserStore{}
mockUserStore.On("GetProfileByIds", []string{"123"}, &store.UserGetByIdsOpts{}, true).Return(fakeUser, nil)
mockUserStore.On("GetProfileByIds", []string{"123"}, &store.UserGetByIdsOpts{}, false).Return(fakeUser, nil)

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

@@ -62,8 +62,9 @@ func (s LocalCachePostStore) InvalidateLastPostTimeCache(channelId string) {
func (s LocalCachePostStore) GetEtag(channelId string, allowFromCache bool) string {
if allowFromCache {
if lastTime := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, channelId); lastTime != nil {
return fmt.Sprintf("%v.%v", model.CurrentVersion, lastTime.(int64))
var lastTime int64
if err := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, channelId, &lastTime); err == nil {
return fmt.Sprintf("%v.%v", model.CurrentVersion, lastTime)
}
}
@@ -82,7 +83,8 @@ func (s LocalCachePostStore) GetPostsSince(options model.GetPostsSinceOptions, a
if allowFromCache {
// If the last post in the channel's time is less than or equal to the time we are getting posts since,
// we can safely return no posts.
if lastTime := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, options.ChannelId); lastTime != nil && lastTime.(int64) <= options.Time {
var lastTime int64
if err := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, options.ChannelId, &lastTime); err == nil && lastTime <= options.Time {
list := model.NewPostList()
return list, nil
}
@@ -111,8 +113,9 @@ func (s LocalCachePostStore) GetPosts(options model.GetPostsOptions, allowFromCa
offset := options.PerPage * options.Page
// Caching only occurs on limits of 30 and 60, the common limits requested by MM clients
if offset == 0 && (options.PerPage == 60 || options.PerPage == 30) {
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.postLastPostsCache, fmt.Sprintf("%s%v", options.ChannelId, options.PerPage)); cacheItem != nil {
return cacheItem.(*model.PostList), nil
var cacheItem *model.PostList
if err := s.rootStore.doStandardReadCache(s.rootStore.postLastPostsCache, fmt.Sprintf("%s%v", options.ChannelId, options.PerPage), &cacheItem); err == nil {
return cacheItem, nil
}
}

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

@@ -36,8 +36,9 @@ func (s LocalCacheReactionStore) GetForPost(postId string, allowFromCache bool)
return s.ReactionStore.GetForPost(postId, false)
}
if reaction := s.rootStore.doStandardReadCache(s.rootStore.reactionCache, postId); reaction != nil {
return reaction.([]*model.Reaction), nil
var reaction []*model.Reaction
if err := s.rootStore.doStandardReadCache(s.rootStore.reactionCache, postId, &reaction); err == nil {
return reaction, nil
}
reaction, err := s.ReactionStore.GetForPost(postId, false)

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

@@ -41,8 +41,9 @@ func (s LocalCacheRoleStore) Save(role *model.Role) (*model.Role, *model.AppErro
}
func (s LocalCacheRoleStore) GetByName(name string) (*model.Role, *model.AppError) {
if role := s.rootStore.doStandardReadCache(s.rootStore.roleCache, name); role != nil {
return role.(*model.Role), nil
var role *model.Role
if err := s.rootStore.doStandardReadCache(s.rootStore.roleCache, name, &role); err == nil {
return role, nil
}
role, err := s.RoleStore.GetByName(name)
@@ -58,8 +59,9 @@ func (s LocalCacheRoleStore) GetByNames(names []string) ([]*model.Role, *model.A
var rolesToQuery []string
for _, roleName := range names {
if role := s.rootStore.doStandardReadCache(s.rootStore.roleCache, roleName); role != nil {
foundRoles = append(foundRoles, role.(*model.Role))
var role *model.Role
if err := s.rootStore.doStandardReadCache(s.rootStore.roleCache, roleName, &role); err == nil {
foundRoles = append(foundRoles, role)
} else {
rolesToQuery = append(rolesToQuery, roleName)
}
@@ -95,8 +97,9 @@ func (s LocalCacheRoleStore) PermanentDeleteAll() *model.AppError {
func (s LocalCacheRoleStore) ChannelHigherScopedPermissions(roleNames []string) (map[string]*model.RolePermissions, *model.AppError) {
sort.Strings(roleNames)
cacheKey := strings.Join(roleNames, "/")
if rolePermissionsMap := s.rootStore.doStandardReadCache(s.rootStore.rolePermissionsCache, cacheKey); rolePermissionsMap != nil {
return rolePermissionsMap.(map[string]*model.RolePermissions), nil
var rolePermissionsMap map[string]*model.RolePermissions
if err := s.rootStore.doStandardReadCache(s.rootStore.rolePermissionsCache, cacheKey, &rolePermissionsMap); err == nil {
return rolePermissionsMap, nil
}
rolePermissionsMap, err := s.RoleStore.ChannelHigherScopedPermissions(roleNames)

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

@@ -29,8 +29,9 @@ func (s LocalCacheSchemeStore) Save(scheme *model.Scheme) (*model.Scheme, error)
}
func (s LocalCacheSchemeStore) Get(schemeId string) (*model.Scheme, error) {
if scheme := s.rootStore.doStandardReadCache(s.rootStore.schemeCache, schemeId); scheme != nil {
return scheme.(*model.Scheme), nil
var scheme *model.Scheme
if err := s.rootStore.doStandardReadCache(s.rootStore.schemeCache, schemeId, &scheme); err == nil {
return scheme, nil
}
scheme, err := s.SchemeStore.Get(schemeId)

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

@@ -40,8 +40,9 @@ func (s LocalCacheTeamStore) GetUserTeamIds(userID string, allowFromCache bool)
return s.TeamStore.GetUserTeamIds(userID, allowFromCache)
}
if userTeamIds := s.rootStore.doStandardReadCache(s.rootStore.teamAllTeamIdsForUserCache, userID); userTeamIds != nil {
return userTeamIds.([]string), nil
var userTeamIds []string
if err := s.rootStore.doStandardReadCache(s.rootStore.teamAllTeamIdsForUserCache, userID, &userTeamIds); err == nil {
return userTeamIds, nil
}
userTeamIds, err := s.TeamStore.GetUserTeamIds(userID, allowFromCache)

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

@@ -45,9 +45,10 @@ func (s LocalCacheTermsOfServiceStore) Save(termsOfService *model.TermsOfService
func (s LocalCacheTermsOfServiceStore) GetLatest(allowFromCache bool) (*model.TermsOfService, error) {
if allowFromCache {
if s.rootStore.termsOfServiceCache.Len() != 0 {
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.termsOfServiceCache, LATEST_KEY); cacheItem != nil {
return cacheItem.(*model.TermsOfService), nil
if len, err := s.rootStore.termsOfServiceCache.Len(); err == nil && len != 0 {
var cacheItem *model.TermsOfService
if err := s.rootStore.doStandardReadCache(s.rootStore.termsOfServiceCache, LATEST_KEY, &cacheItem); err == nil {
return cacheItem, nil
}
}
}
@@ -64,8 +65,9 @@ func (s LocalCacheTermsOfServiceStore) GetLatest(allowFromCache bool) (*model.Te
func (s LocalCacheTermsOfServiceStore) Get(id string, allowFromCache bool) (*model.TermsOfService, error) {
if allowFromCache {
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.termsOfServiceCache, id); cacheItem != nil {
return cacheItem.(*model.TermsOfService), nil
var cacheItem *model.TermsOfService
if err := s.rootStore.doStandardReadCache(s.rootStore.termsOfServiceCache, id, &cacheItem); err == nil {
return cacheItem, nil
}
}

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

@@ -48,15 +48,16 @@ func (s LocalCacheUserStore) InvalidateProfileCacheForUser(userId string) {
}
func (s LocalCacheUserStore) InvalidateProfilesInChannelCacheByUser(userId string) {
keys := s.rootStore.profilesInChannelCache.Keys()
for _, key := range keys {
if cacheItem, ok := s.rootStore.profilesInChannelCache.Get(key); ok {
userMap := cacheItem.(map[string]*model.User)
if _, userInCache := userMap[userId]; userInCache {
s.rootStore.doInvalidateCacheCluster(s.rootStore.profilesInChannelCache, key)
if s.rootStore.metrics != nil {
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Profiles in Channel - Remove by User")
keys, err := s.rootStore.profilesInChannelCache.Keys()
if err == nil {
for _, key := range keys {
var userMap map[string]*model.User
if err = s.rootStore.profilesInChannelCache.Get(key, &userMap); err == nil {
if _, userInCache := userMap[userId]; userInCache {
s.rootStore.doInvalidateCacheCluster(s.rootStore.profilesInChannelCache, key)
if s.rootStore.metrics != nil {
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Profiles in Channel - Remove by User")
}
}
}
}
@@ -72,8 +73,8 @@ func (s LocalCacheUserStore) InvalidateProfilesInChannelCache(channelId string)
func (s LocalCacheUserStore) GetAllProfilesInChannel(channelId string, allowFromCache bool) (map[string]*model.User, *model.AppError) {
if allowFromCache {
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.profilesInChannelCache, channelId); cacheItem != nil {
cachedMap := cacheItem.(map[string]*model.User)
var cachedMap map[string]*model.User
if err := s.rootStore.doStandardReadCache(s.rootStore.profilesInChannelCache, channelId, &cachedMap); err == nil {
return deepCopyUserMap(cachedMap), nil
}
}
@@ -103,10 +104,10 @@ func (s LocalCacheUserStore) GetProfileByIds(userIds []string, options *store.Us
remainingUserIds := make([]string, 0)
for _, userId := range userIds {
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, userId); cacheItem != nil {
u := cacheItem.(*model.User)
if options.Since == 0 || u.UpdateAt > options.Since {
users = append(users, u.DeepCopy())
var cacheItem *model.User
if err := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, userId, &cacheItem); err == nil {
if options.Since == 0 || cacheItem.UpdateAt > options.Since {
users = append(users, cacheItem.DeepCopy())
}
} else {
remainingUserIds = append(remainingUserIds, userId)
@@ -137,13 +138,12 @@ func (s LocalCacheUserStore) GetProfileByIds(userIds []string, options *store.Us
// if it is present. Otherwise, it fetches the entry from the store and stores it in the
// cache.
func (s LocalCacheUserStore) Get(id string) (*model.User, *model.AppError) {
cacheItem := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, id)
if cacheItem != nil {
var cacheItem *model.User
if err := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, id, &cacheItem); err == nil {
if s.rootStore.metrics != nil {
s.rootStore.metrics.AddMemCacheHitCounter("Profile By Id", float64(1))
}
u := cacheItem.(*model.User)
return u.DeepCopy(), nil
return cacheItem.DeepCopy(), nil
}
if s.rootStore.metrics != nil {
s.rootStore.metrics.AddMemCacheMissCounter("Profile By Id", float64(1))

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

@@ -21,7 +21,11 @@ func TestUserStore(t *testing.T) {
func TestUserStoreCache(t *testing.T) {
fakeUserIds := []string{"123"}
fakeUser := []*model.User{{Id: "123", AuthData: model.NewString("")}}
fakeUser := []*model.User{{
Id: "123",
AuthData: model.NewString("authData"),
AuthService: "authService",
}}
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
@@ -181,7 +185,11 @@ func TestUserStoreProfilesInChannelCache(t *testing.T) {
func TestUserStoreGetCache(t *testing.T) {
fakeUserId := "123"
fakeUser := &model.User{Id: "123", AuthData: model.NewString("")}
fakeUser := &model.User{
Id: "123",
AuthData: model.NewString("authData"),
AuthService: "authService",
}
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
mockStore := getMockStore()
mockCacheProvider := getMockCacheProvider()

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

@@ -41,8 +41,9 @@ func (s LocalCacheWebhookStore) GetIncoming(id string, allowFromCache bool) (*mo
return s.WebhookStore.GetIncoming(id, allowFromCache)
}
if incomingWebhook := s.rootStore.doStandardReadCache(s.rootStore.webhookCache, id); incomingWebhook != nil {
return incomingWebhook.(*model.IncomingWebhook), nil
var incomingWebhook *model.IncomingWebhook
if err := s.rootStore.doStandardReadCache(s.rootStore.webhookCache, id, &incomingWebhook); err == nil {
return incomingWebhook, nil
}
incomingWebhook, err := s.WebhookStore.GetIncoming(id, allowFromCache)

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

@@ -1,145 +0,0 @@
// 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)
}

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

@@ -1,57 +0,0 @@
// 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
}

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

@@ -82,7 +82,7 @@ func setupTestHelper(t testing.TB, store store.Store, includeCacheLayer bool) *T
}
if includeCacheLayer {
// Adds the cache layer to the test store
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider)
s.Store = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider2)
}
prevListenAddress := *s.Config().ServiceSettings.ListenAddress