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
Этот коммит содержится в:
@@ -98,7 +98,7 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent
|
|||||||
}
|
}
|
||||||
if includeCache {
|
if includeCache {
|
||||||
// Adds the cache layer to the test store
|
// 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{
|
th := &TestHelper{
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
|
|||||||
|
|
||||||
if includeCacheLayer {
|
if includeCacheLayer {
|
||||||
// Adds the cache layer to the test store
|
// 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{
|
th := &TestHelper{
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
s.sqlStore,
|
s.sqlStore,
|
||||||
s.Metrics,
|
s.Metrics,
|
||||||
s.Cluster,
|
s.Cluster,
|
||||||
s.CacheProvider,
|
s.CacheProvider2,
|
||||||
),
|
),
|
||||||
s.SearchEngine,
|
s.SearchEngine,
|
||||||
s.Config(),
|
s.Config(),
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// Adds the cache layer to the test store
|
// 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{
|
th := &TestHelper{
|
||||||
App: app.New(app.ServerConnector(s)),
|
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 returns the cluster event configured when this cache was created.
|
||||||
GetInvalidateClusterEvent() string
|
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.
|
// LRU is a thread-safe fixed size LRU cache.
|
||||||
type LRU struct {
|
type LRU struct {
|
||||||
|
name string
|
||||||
size int
|
size int
|
||||||
evictList *list.List
|
evictList *list.List
|
||||||
items map[string]*list.Element
|
items map[string]*list.Element
|
||||||
@@ -25,6 +26,7 @@ type LRU struct {
|
|||||||
|
|
||||||
// LRUOptions contains options for initializing LRU cache
|
// LRUOptions contains options for initializing LRU cache
|
||||||
type LRUOptions struct {
|
type LRUOptions struct {
|
||||||
|
Name string
|
||||||
Size int
|
Size int
|
||||||
DefaultExpiry time.Duration
|
DefaultExpiry time.Duration
|
||||||
InvalidateClusterEvent string
|
InvalidateClusterEvent string
|
||||||
@@ -41,6 +43,7 @@ type entry struct {
|
|||||||
// NewLRU creates an LRU of the given size.
|
// NewLRU creates an LRU of the given size.
|
||||||
func NewLRU(opts *LRUOptions) Cache {
|
func NewLRU(opts *LRUOptions) Cache {
|
||||||
return &LRU{
|
return &LRU{
|
||||||
|
name: opts.Name,
|
||||||
size: opts.Size,
|
size: opts.Size,
|
||||||
evictList: list.New(),
|
evictList: list.New(),
|
||||||
items: make(map[string]*list.Element, opts.Size),
|
items: make(map[string]*list.Element, opts.Size),
|
||||||
@@ -127,6 +130,11 @@ func (l *LRU) GetInvalidateClusterEvent() string {
|
|||||||
return l.invalidateClusterEvent
|
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 {
|
func (l *LRU) set(key string, value interface{}, ttl time.Duration) error {
|
||||||
var expires time.Time
|
var expires time.Time
|
||||||
if ttl > 0 {
|
if ttl > 0 {
|
||||||
|
|||||||
167
services/cache2/mocks/Cache.go
Обычный файл
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
Обычный файл
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
|
// NewCache creates a new cache with given opts
|
||||||
func (c *cacheProvider) NewCache(opts *CacheOptions) Cache {
|
func (c *cacheProvider) NewCache(opts *CacheOptions) Cache {
|
||||||
return NewLRU(&LRUOptions{
|
return NewLRU(&LRUOptions{
|
||||||
|
Name: opts.Name,
|
||||||
Size: opts.Size,
|
Size: opts.Size,
|
||||||
DefaultExpiry: opts.DefaultExpiry,
|
DefaultExpiry: opts.DefaultExpiry,
|
||||||
InvalidateClusterEvent: opts.InvalidateClusterEvent,
|
InvalidateClusterEvent: opts.InvalidateClusterEvent,
|
||||||
|
|||||||
@@ -89,8 +89,9 @@ func (s LocalCacheChannelStore) InvalidateChannel(channelId string) {
|
|||||||
|
|
||||||
func (s LocalCacheChannelStore) GetMemberCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
|
func (s LocalCacheChannelStore) GetMemberCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if count := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId); count != nil {
|
var count int64
|
||||||
return count.(int64), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId, &count); err == nil {
|
||||||
|
return count, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count, err := s.ChannelStore.GetMemberCount(channelId, allowFromCache)
|
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) {
|
func (s LocalCacheChannelStore) GetGuestCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if count := s.rootStore.doStandardReadCache(s.rootStore.channelGuestCountCache, channelId); count != nil {
|
var count int64
|
||||||
return count.(int64), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.channelGuestCountCache, channelId, &count); err == nil {
|
||||||
|
return count, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count, err := s.ChannelStore.GetGuestCount(channelId, allowFromCache)
|
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 {
|
func (s LocalCacheChannelStore) GetMemberCountFromCache(channelId string) int64 {
|
||||||
if count := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId); count != nil {
|
var count int64
|
||||||
return count.(int64)
|
if err := s.rootStore.doStandardReadCache(s.rootStore.channelMemberCountsCache, channelId, &count); err == nil {
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := s.GetMemberCount(channelId, true)
|
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) {
|
func (s LocalCacheChannelStore) GetPinnedPostCount(channelId string, allowFromCache bool) (int64, *model.AppError) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if count := s.rootStore.doStandardReadCache(s.rootStore.channelPinnedPostCountsCache, channelId); count != nil {
|
var count int64
|
||||||
return count.(int64), nil
|
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) {
|
func (s LocalCacheChannelStore) Get(id string, allowFromCache bool) (*model.Channel, error) {
|
||||||
|
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.channelByIdCache, id); cacheItem != nil {
|
var cacheItem *model.Channel
|
||||||
ch := cacheItem.(*model.Channel).DeepCopy()
|
if err := s.rootStore.doStandardReadCache(s.rootStore.channelByIdCache, id, &cacheItem); err == nil {
|
||||||
|
ch := cacheItem.DeepCopy()
|
||||||
return ch, nil
|
return ch, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
package localcachelayer
|
package localcachelayer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mattermost/mattermost-server/v5/model"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/v5/model"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func (es LocalCacheEmojiStore) getFromCacheById(id string) (*model.Emoji, bool) {
|
||||||
if emoji := es.rootStore.doStandardReadCache(es.rootStore.emojiCacheById, id); emoji != nil {
|
var emoji *model.Emoji
|
||||||
return emoji.(*model.Emoji), true
|
if err := es.rootStore.doStandardReadCache(es.rootStore.emojiCacheById, id, &emoji); err == nil {
|
||||||
|
return emoji, true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es LocalCacheEmojiStore) getFromCacheByName(name string) (*model.Emoji, bool) {
|
func (es LocalCacheEmojiStore) getFromCacheByName(name string) (*model.Emoji, bool) {
|
||||||
if emojiId := es.rootStore.doStandardReadCache(es.rootStore.emojiIdCacheByName, name); emojiId != nil {
|
var emojiId string
|
||||||
return es.getFromCacheById(emojiId.(string))
|
if err := es.rootStore.doStandardReadCache(es.rootStore.emojiIdCacheByName, name, &emojiId); err == nil {
|
||||||
|
return es.getFromCacheById(emojiId)
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ func (s LocalCacheFileInfoStore) GetForPost(postId string, readFromMaster, inclu
|
|||||||
cacheKey += "_deleted"
|
cacheKey += "_deleted"
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileInfo := s.rootStore.doStandardReadCache(s.rootStore.fileInfoCache, cacheKey); fileInfo != nil {
|
var fileInfo []*model.FileInfo
|
||||||
return fileInfo.([]*model.FileInfo), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.fileInfoCache, cacheKey, &fileInfo); err == nil {
|
||||||
|
return fileInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fileInfos, err := s.FileInfoStore.GetForPost(postId, readFromMaster, includeDeleted, allowFromCache)
|
fileInfos, err := s.FileInfoStore.GetForPost(postId, readFromMaster, includeDeleted, allowFromCache)
|
||||||
|
|||||||
@@ -4,9 +4,11 @@
|
|||||||
package localcachelayer
|
package localcachelayer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v5/einterfaces"
|
"github.com/mattermost/mattermost-server/v5/einterfaces"
|
||||||
"github.com/mattermost/mattermost-server/v5/model"
|
"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"
|
"github.com/mattermost/mattermost-server/v5/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -66,47 +68,47 @@ type LocalCacheStore struct {
|
|||||||
cluster einterfaces.ClusterInterface
|
cluster einterfaces.ClusterInterface
|
||||||
|
|
||||||
reaction LocalCacheReactionStore
|
reaction LocalCacheReactionStore
|
||||||
reactionCache cache.Cache
|
reactionCache cache2.Cache
|
||||||
|
|
||||||
fileInfo LocalCacheFileInfoStore
|
fileInfo LocalCacheFileInfoStore
|
||||||
fileInfoCache cache.Cache
|
fileInfoCache cache2.Cache
|
||||||
|
|
||||||
role LocalCacheRoleStore
|
role LocalCacheRoleStore
|
||||||
roleCache cache.Cache
|
roleCache cache2.Cache
|
||||||
rolePermissionsCache cache.Cache
|
rolePermissionsCache cache2.Cache
|
||||||
|
|
||||||
scheme LocalCacheSchemeStore
|
scheme LocalCacheSchemeStore
|
||||||
schemeCache cache.Cache
|
schemeCache cache2.Cache
|
||||||
|
|
||||||
emoji LocalCacheEmojiStore
|
emoji LocalCacheEmojiStore
|
||||||
emojiCacheById cache.Cache
|
emojiCacheById cache2.Cache
|
||||||
emojiIdCacheByName cache.Cache
|
emojiIdCacheByName cache2.Cache
|
||||||
|
|
||||||
channel LocalCacheChannelStore
|
channel LocalCacheChannelStore
|
||||||
channelMemberCountsCache cache.Cache
|
channelMemberCountsCache cache2.Cache
|
||||||
channelGuestCountCache cache.Cache
|
channelGuestCountCache cache2.Cache
|
||||||
channelPinnedPostCountsCache cache.Cache
|
channelPinnedPostCountsCache cache2.Cache
|
||||||
channelByIdCache cache.Cache
|
channelByIdCache cache2.Cache
|
||||||
|
|
||||||
webhook LocalCacheWebhookStore
|
webhook LocalCacheWebhookStore
|
||||||
webhookCache cache.Cache
|
webhookCache cache2.Cache
|
||||||
|
|
||||||
post LocalCachePostStore
|
post LocalCachePostStore
|
||||||
postLastPostsCache cache.Cache
|
postLastPostsCache cache2.Cache
|
||||||
lastPostTimeCache cache.Cache
|
lastPostTimeCache cache2.Cache
|
||||||
|
|
||||||
user LocalCacheUserStore
|
user LocalCacheUserStore
|
||||||
userProfileByIdsCache cache.Cache
|
userProfileByIdsCache cache2.Cache
|
||||||
profilesInChannelCache cache.Cache
|
profilesInChannelCache cache2.Cache
|
||||||
|
|
||||||
team LocalCacheTeamStore
|
team LocalCacheTeamStore
|
||||||
teamAllTeamIdsForUserCache cache.Cache
|
teamAllTeamIdsForUserCache cache2.Cache
|
||||||
|
|
||||||
termsOfService LocalCacheTermsOfServiceStore
|
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{
|
localCacheStore := LocalCacheStore{
|
||||||
Store: baseStore,
|
Store: baseStore,
|
||||||
@@ -114,54 +116,144 @@ func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterf
|
|||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
}
|
}
|
||||||
// Reactions
|
// 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}
|
localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Roles
|
// Roles
|
||||||
localCacheStore.roleCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES)
|
localCacheStore.roleCache = cacheProvider.NewCache(&cache2.CacheOptions{
|
||||||
localCacheStore.rolePermissionsCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "RolePermission", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS)
|
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}
|
localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Schemes
|
// 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}
|
localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// FileInfo
|
// 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}
|
localCacheStore.fileInfo = LocalCacheFileInfoStore{FileInfoStore: baseStore.FileInfo(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Webhooks
|
// 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}
|
localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Emojis
|
// Emojis
|
||||||
localCacheStore.emojiCacheById = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiById", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID)
|
localCacheStore.emojiCacheById = cacheProvider.NewCache(&cache2.CacheOptions{
|
||||||
localCacheStore.emojiIdCacheByName = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiByName", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME)
|
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}
|
localCacheStore.emoji = LocalCacheEmojiStore{EmojiStore: baseStore.Emoji(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Channels
|
// 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.channelPinnedPostCountsCache = cacheProvider.NewCache(&cache2.CacheOptions{
|
||||||
localCacheStore.channelMemberCountsCache = cacheProvider.NewCacheWithParams(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE, "ChannelMemberCounts", CHANNEL_MEMBERS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS)
|
Size: CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SIZE,
|
||||||
localCacheStore.channelGuestCountCache = cacheProvider.NewCacheWithParams(CHANNEL_GUEST_COUNT_CACHE_SIZE, "ChannelGuestsCount", CHANNEL_GUEST_COUNT_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT)
|
Name: "ChannelPinnedPostsCounts",
|
||||||
localCacheStore.channelByIdCache = cacheProvider.NewCacheWithParams(model.CHANNEL_CACHE_SIZE, "channelById", CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL)
|
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}
|
localCacheStore.channel = LocalCacheChannelStore{ChannelStore: baseStore.Channel(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Posts
|
// Posts
|
||||||
localCacheStore.postLastPostsCache = cacheProvider.NewCacheWithParams(LAST_POSTS_CACHE_SIZE, "LastPost", LAST_POSTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS)
|
localCacheStore.postLastPostsCache = cacheProvider.NewCache(&cache2.CacheOptions{
|
||||||
localCacheStore.lastPostTimeCache = cacheProvider.NewCacheWithParams(LAST_POST_TIME_CACHE_SIZE, "LastPostTime", LAST_POST_TIME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME)
|
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}
|
localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// TOS
|
// 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}
|
localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Users
|
// 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.userProfileByIdsCache = cacheProvider.NewCache(&cache2.CacheOptions{
|
||||||
localCacheStore.profilesInChannelCache = cacheProvider.NewCacheWithParams(PROFILES_IN_CHANNEL_CACHE_SIZE, "ProfilesInChannel", PROFILES_IN_CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL)
|
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}
|
localCacheStore.user = LocalCacheUserStore{UserStore: baseStore.User(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
// Teams
|
// 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}
|
localCacheStore.team = LocalCacheTeamStore{TeamStore: baseStore.Team(), rootStore: &localCacheStore}
|
||||||
|
|
||||||
if cluster != nil {
|
if cluster != nil {
|
||||||
@@ -236,7 +328,7 @@ func (s LocalCacheStore) DropAllTables() {
|
|||||||
s.Store.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)
|
cache.Remove(key)
|
||||||
if s.cluster != nil {
|
if s.cluster != nil {
|
||||||
msg := &model.ClusterMessage{
|
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{}) {
|
func (s *LocalCacheStore) doStandardAddToCache(cache cache2.Cache, key string, value interface{}) {
|
||||||
cache.AddWithDefaultExpires(key, value)
|
cache.SetWithDefaultExpiry(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LocalCacheStore) doStandardReadCache(cache cache.Cache, key string) interface{} {
|
func (s *LocalCacheStore) doStandardReadCache(cache cache2.Cache, key string, value interface{}) error {
|
||||||
if cacheItem, ok := cache.Get(key); ok {
|
if err := cache.Get(key, value); err == nil {
|
||||||
if s.metrics != nil {
|
if s.metrics != nil {
|
||||||
s.metrics.IncrementMemCacheHitCounter(cache.Name())
|
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()
|
cache.Purge()
|
||||||
if s.cluster != nil {
|
if s.cluster != nil {
|
||||||
msg := &model.ClusterMessage{
|
msg := &model.ClusterMessage{
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/v5/services/cache2"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v5/model"
|
"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"
|
||||||
"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
|
"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
|
||||||
"github.com/mattermost/mattermost-server/v5/testlib"
|
"github.com/mattermost/mattermost-server/v5/testlib"
|
||||||
@@ -17,117 +19,10 @@ import (
|
|||||||
|
|
||||||
var mainHelper *testlib.MainHelper
|
var mainHelper *testlib.MainHelper
|
||||||
|
|
||||||
func getMockCacheProvider() *mocks.CacheProvider {
|
func getMockCacheProvider() cache2.Provider {
|
||||||
mockCacheProvider := mocks.CacheProvider{}
|
mockCacheProvider := cachemocks.Provider{}
|
||||||
//todo: replace this line with mocks for all tests
|
mockCacheProvider.On("NewCache", mock.Anything).
|
||||||
mockCacheProvider.On("NewCacheWithParams",
|
Return(cache2.NewLRU(&cache2.LRUOptions{Size: 128}))
|
||||||
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))
|
|
||||||
|
|
||||||
return &mockCacheProvider
|
return &mockCacheProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +125,11 @@ func getMockStore() *mocks.Store {
|
|||||||
mockTermsOfServiceStore.On("Get", "123", false).Return(&fakeTermsOfService, nil)
|
mockTermsOfServiceStore.On("Get", "123", false).Return(&fakeTermsOfService, nil)
|
||||||
mockStore.On("TermsOfService").Return(&mockTermsOfServiceStore)
|
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 := mocks.UserStore{}
|
||||||
mockUserStore.On("GetProfileByIds", []string{"123"}, &store.UserGetByIdsOpts{}, true).Return(fakeUser, nil)
|
mockUserStore.On("GetProfileByIds", []string{"123"}, &store.UserGetByIdsOpts{}, true).Return(fakeUser, nil)
|
||||||
mockUserStore.On("GetProfileByIds", []string{"123"}, &store.UserGetByIdsOpts{}, false).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 {
|
func (s LocalCachePostStore) GetEtag(channelId string, allowFromCache bool) string {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if lastTime := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, channelId); lastTime != nil {
|
var lastTime int64
|
||||||
return fmt.Sprintf("%v.%v", model.CurrentVersion, 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 allowFromCache {
|
||||||
// If the last post in the channel's time is less than or equal to the time we are getting posts since,
|
// 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.
|
// 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()
|
list := model.NewPostList()
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
@@ -111,8 +113,9 @@ func (s LocalCachePostStore) GetPosts(options model.GetPostsOptions, allowFromCa
|
|||||||
offset := options.PerPage * options.Page
|
offset := options.PerPage * options.Page
|
||||||
// Caching only occurs on limits of 30 and 60, the common limits requested by MM clients
|
// 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 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 {
|
var cacheItem *model.PostList
|
||||||
return cacheItem.(*model.PostList), nil
|
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)
|
return s.ReactionStore.GetForPost(postId, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if reaction := s.rootStore.doStandardReadCache(s.rootStore.reactionCache, postId); reaction != nil {
|
var reaction []*model.Reaction
|
||||||
return reaction.([]*model.Reaction), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.reactionCache, postId, &reaction); err == nil {
|
||||||
|
return reaction, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
reaction, err := s.ReactionStore.GetForPost(postId, false)
|
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) {
|
func (s LocalCacheRoleStore) GetByName(name string) (*model.Role, *model.AppError) {
|
||||||
if role := s.rootStore.doStandardReadCache(s.rootStore.roleCache, name); role != nil {
|
var role *model.Role
|
||||||
return role.(*model.Role), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.roleCache, name, &role); err == nil {
|
||||||
|
return role, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
role, err := s.RoleStore.GetByName(name)
|
role, err := s.RoleStore.GetByName(name)
|
||||||
@@ -58,8 +59,9 @@ func (s LocalCacheRoleStore) GetByNames(names []string) ([]*model.Role, *model.A
|
|||||||
var rolesToQuery []string
|
var rolesToQuery []string
|
||||||
|
|
||||||
for _, roleName := range names {
|
for _, roleName := range names {
|
||||||
if role := s.rootStore.doStandardReadCache(s.rootStore.roleCache, roleName); role != nil {
|
var role *model.Role
|
||||||
foundRoles = append(foundRoles, role.(*model.Role))
|
if err := s.rootStore.doStandardReadCache(s.rootStore.roleCache, roleName, &role); err == nil {
|
||||||
|
foundRoles = append(foundRoles, role)
|
||||||
} else {
|
} else {
|
||||||
rolesToQuery = append(rolesToQuery, roleName)
|
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) {
|
func (s LocalCacheRoleStore) ChannelHigherScopedPermissions(roleNames []string) (map[string]*model.RolePermissions, *model.AppError) {
|
||||||
sort.Strings(roleNames)
|
sort.Strings(roleNames)
|
||||||
cacheKey := strings.Join(roleNames, "/")
|
cacheKey := strings.Join(roleNames, "/")
|
||||||
if rolePermissionsMap := s.rootStore.doStandardReadCache(s.rootStore.rolePermissionsCache, cacheKey); rolePermissionsMap != nil {
|
var rolePermissionsMap map[string]*model.RolePermissions
|
||||||
return rolePermissionsMap.(map[string]*model.RolePermissions), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.rolePermissionsCache, cacheKey, &rolePermissionsMap); err == nil {
|
||||||
|
return rolePermissionsMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rolePermissionsMap, err := s.RoleStore.ChannelHigherScopedPermissions(roleNames)
|
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) {
|
func (s LocalCacheSchemeStore) Get(schemeId string) (*model.Scheme, error) {
|
||||||
if scheme := s.rootStore.doStandardReadCache(s.rootStore.schemeCache, schemeId); scheme != nil {
|
var scheme *model.Scheme
|
||||||
return scheme.(*model.Scheme), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.schemeCache, schemeId, &scheme); err == nil {
|
||||||
|
return scheme, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme, err := s.SchemeStore.Get(schemeId)
|
scheme, err := s.SchemeStore.Get(schemeId)
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ func (s LocalCacheTeamStore) GetUserTeamIds(userID string, allowFromCache bool)
|
|||||||
return s.TeamStore.GetUserTeamIds(userID, allowFromCache)
|
return s.TeamStore.GetUserTeamIds(userID, allowFromCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
if userTeamIds := s.rootStore.doStandardReadCache(s.rootStore.teamAllTeamIdsForUserCache, userID); userTeamIds != nil {
|
var userTeamIds []string
|
||||||
return userTeamIds.([]string), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.teamAllTeamIdsForUserCache, userID, &userTeamIds); err == nil {
|
||||||
|
return userTeamIds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
userTeamIds, err := s.TeamStore.GetUserTeamIds(userID, allowFromCache)
|
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) {
|
func (s LocalCacheTermsOfServiceStore) GetLatest(allowFromCache bool) (*model.TermsOfService, error) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if s.rootStore.termsOfServiceCache.Len() != 0 {
|
if len, err := s.rootStore.termsOfServiceCache.Len(); err == nil && len != 0 {
|
||||||
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.termsOfServiceCache, LATEST_KEY); cacheItem != nil {
|
var cacheItem *model.TermsOfService
|
||||||
return cacheItem.(*model.TermsOfService), nil
|
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) {
|
func (s LocalCacheTermsOfServiceStore) Get(id string, allowFromCache bool) (*model.TermsOfService, error) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.termsOfServiceCache, id); cacheItem != nil {
|
var cacheItem *model.TermsOfService
|
||||||
return cacheItem.(*model.TermsOfService), nil
|
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) {
|
func (s LocalCacheUserStore) InvalidateProfilesInChannelCacheByUser(userId string) {
|
||||||
keys := s.rootStore.profilesInChannelCache.Keys()
|
keys, err := s.rootStore.profilesInChannelCache.Keys()
|
||||||
|
if err == nil {
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
if cacheItem, ok := s.rootStore.profilesInChannelCache.Get(key); ok {
|
var userMap map[string]*model.User
|
||||||
userMap := cacheItem.(map[string]*model.User)
|
if err = s.rootStore.profilesInChannelCache.Get(key, &userMap); err == nil {
|
||||||
if _, userInCache := userMap[userId]; userInCache {
|
if _, userInCache := userMap[userId]; userInCache {
|
||||||
s.rootStore.doInvalidateCacheCluster(s.rootStore.profilesInChannelCache, key)
|
s.rootStore.doInvalidateCacheCluster(s.rootStore.profilesInChannelCache, key)
|
||||||
if s.rootStore.metrics != nil {
|
if s.rootStore.metrics != nil {
|
||||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Profiles in Channel - Remove by User")
|
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) {
|
func (s LocalCacheUserStore) GetAllProfilesInChannel(channelId string, allowFromCache bool) (map[string]*model.User, *model.AppError) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.profilesInChannelCache, channelId); cacheItem != nil {
|
var cachedMap map[string]*model.User
|
||||||
cachedMap := cacheItem.(map[string]*model.User)
|
if err := s.rootStore.doStandardReadCache(s.rootStore.profilesInChannelCache, channelId, &cachedMap); err == nil {
|
||||||
return deepCopyUserMap(cachedMap), nil
|
return deepCopyUserMap(cachedMap), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,10 +104,10 @@ func (s LocalCacheUserStore) GetProfileByIds(userIds []string, options *store.Us
|
|||||||
remainingUserIds := make([]string, 0)
|
remainingUserIds := make([]string, 0)
|
||||||
|
|
||||||
for _, userId := range userIds {
|
for _, userId := range userIds {
|
||||||
if cacheItem := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, userId); cacheItem != nil {
|
var cacheItem *model.User
|
||||||
u := cacheItem.(*model.User)
|
if err := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, userId, &cacheItem); err == nil {
|
||||||
if options.Since == 0 || u.UpdateAt > options.Since {
|
if options.Since == 0 || cacheItem.UpdateAt > options.Since {
|
||||||
users = append(users, u.DeepCopy())
|
users = append(users, cacheItem.DeepCopy())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
remainingUserIds = append(remainingUserIds, userId)
|
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
|
// if it is present. Otherwise, it fetches the entry from the store and stores it in the
|
||||||
// cache.
|
// cache.
|
||||||
func (s LocalCacheUserStore) Get(id string) (*model.User, *model.AppError) {
|
func (s LocalCacheUserStore) Get(id string) (*model.User, *model.AppError) {
|
||||||
cacheItem := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, id)
|
var cacheItem *model.User
|
||||||
if cacheItem != nil {
|
if err := s.rootStore.doStandardReadCache(s.rootStore.userProfileByIdsCache, id, &cacheItem); err == nil {
|
||||||
if s.rootStore.metrics != nil {
|
if s.rootStore.metrics != nil {
|
||||||
s.rootStore.metrics.AddMemCacheHitCounter("Profile By Id", float64(1))
|
s.rootStore.metrics.AddMemCacheHitCounter("Profile By Id", float64(1))
|
||||||
}
|
}
|
||||||
u := cacheItem.(*model.User)
|
return cacheItem.DeepCopy(), nil
|
||||||
return u.DeepCopy(), nil
|
|
||||||
}
|
}
|
||||||
if s.rootStore.metrics != nil {
|
if s.rootStore.metrics != nil {
|
||||||
s.rootStore.metrics.AddMemCacheMissCounter("Profile By Id", float64(1))
|
s.rootStore.metrics.AddMemCacheMissCounter("Profile By Id", float64(1))
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ func TestUserStore(t *testing.T) {
|
|||||||
|
|
||||||
func TestUserStoreCache(t *testing.T) {
|
func TestUserStoreCache(t *testing.T) {
|
||||||
fakeUserIds := []string{"123"}
|
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) {
|
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||||
mockStore := getMockStore()
|
mockStore := getMockStore()
|
||||||
@@ -181,7 +185,11 @@ func TestUserStoreProfilesInChannelCache(t *testing.T) {
|
|||||||
|
|
||||||
func TestUserStoreGetCache(t *testing.T) {
|
func TestUserStoreGetCache(t *testing.T) {
|
||||||
fakeUserId := "123"
|
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) {
|
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||||
mockStore := getMockStore()
|
mockStore := getMockStore()
|
||||||
mockCacheProvider := getMockCacheProvider()
|
mockCacheProvider := getMockCacheProvider()
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ func (s LocalCacheWebhookStore) GetIncoming(id string, allowFromCache bool) (*mo
|
|||||||
return s.WebhookStore.GetIncoming(id, allowFromCache)
|
return s.WebhookStore.GetIncoming(id, allowFromCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
if incomingWebhook := s.rootStore.doStandardReadCache(s.rootStore.webhookCache, id); incomingWebhook != nil {
|
var incomingWebhook *model.IncomingWebhook
|
||||||
return incomingWebhook.(*model.IncomingWebhook), nil
|
if err := s.rootStore.doStandardReadCache(s.rootStore.webhookCache, id, &incomingWebhook); err == nil {
|
||||||
|
return incomingWebhook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
incomingWebhook, err := s.WebhookStore.GetIncoming(id, allowFromCache)
|
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 {
|
if includeCacheLayer {
|
||||||
// Adds the cache layer to the test store
|
// 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
|
prevListenAddress := *s.Config().ServiceSettings.ListenAddress
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user