implement and use striped LRU cache to lower mutex contention (#15764)
* Implement Striped LRU cache * ci * fix Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
96d76760f0
Коммит
349b83f23a
@@ -102,7 +102,11 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent
|
||||
if includeCache {
|
||||
// Adds the cache layer to the test store
|
||||
options = append(options, app.StoreOverride(func(s *app.Server) store.Store {
|
||||
return localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
return lcl
|
||||
}))
|
||||
} else {
|
||||
options = append(options, app.StoreOverride(dbStore))
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
const OPEN_GRAPH_METADATA_CACHE_SIZE = 10000
|
||||
|
||||
var openGraphDataCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var openGraphDataCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: OPEN_GRAPH_METADATA_CACHE_SIZE,
|
||||
})
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
MAX_SERVER_BUSY_SECONDS = 86400
|
||||
)
|
||||
|
||||
var redirectLocationDataCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var redirectLocationDataCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: REDIRECT_LOCATION_CACHE_SIZE,
|
||||
})
|
||||
|
||||
|
||||
@@ -68,7 +68,11 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
|
||||
if includeCacheLayer {
|
||||
// Adds the cache layer to the test store
|
||||
options = append(options, StoreOverride(func(s *Server) store.Store {
|
||||
return localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
return lcl
|
||||
}))
|
||||
} else {
|
||||
options = append(options, StoreOverride(dbStore))
|
||||
|
||||
@@ -22,14 +22,14 @@ func StoreOverride(override interface{}) Option {
|
||||
return func(s *Server) error {
|
||||
switch o := override.(type) {
|
||||
case store.Store:
|
||||
s.newStore = func() store.Store {
|
||||
return o
|
||||
s.newStore = func() (store.Store, error) {
|
||||
return o, nil
|
||||
}
|
||||
return nil
|
||||
|
||||
case func(*Server) store.Store:
|
||||
s.newStore = func() store.Store {
|
||||
return o(s)
|
||||
s.newStore = func() (store.Store, error) {
|
||||
return o(s), nil
|
||||
}
|
||||
return nil
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ const LINK_CACHE_SIZE = 10000
|
||||
const LINK_CACHE_DURATION = 1 * time.Hour
|
||||
const MaxMetadataImageSize = MaxOpenGraphResponseSize
|
||||
|
||||
var linkCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var linkCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: LINK_CACHE_SIZE,
|
||||
})
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -114,7 +115,7 @@ type Server struct {
|
||||
|
||||
timezones *timezones.Timezones
|
||||
|
||||
newStore func() store.Store
|
||||
newStore func() (store.Store, error)
|
||||
|
||||
htmlTemplateWatcher *utils.HTMLTemplateWatcher
|
||||
sessionCache cache.Cache
|
||||
@@ -286,34 +287,51 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
return nil, errors.Wrapf(err, "Unable to connect to cache provider")
|
||||
}
|
||||
|
||||
s.sessionCache = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.SESSION_CACHE_SIZE,
|
||||
})
|
||||
s.seenPendingPostIdsCache = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
var err error
|
||||
if s.sessionCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.SESSION_CACHE_SIZE,
|
||||
Striped: true,
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create session cache")
|
||||
}
|
||||
if s.seenPendingPostIdsCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PENDING_POST_IDS_CACHE_SIZE,
|
||||
})
|
||||
s.statusCache = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.STATUS_CACHE_SIZE,
|
||||
})
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create pending post ids cache")
|
||||
}
|
||||
if s.statusCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.STATUS_CACHE_SIZE,
|
||||
Striped: true,
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create status cache")
|
||||
}
|
||||
|
||||
s.createPushNotificationsHub()
|
||||
|
||||
if err := utils.InitTranslations(s.Config().LocalizationSettings); err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to load Mattermost translation files")
|
||||
if err2 := utils.InitTranslations(s.Config().LocalizationSettings); err2 != nil {
|
||||
return nil, errors.Wrapf(err2, "unable to load Mattermost translation files")
|
||||
}
|
||||
|
||||
s.initEnterprise()
|
||||
|
||||
if s.newStore == nil {
|
||||
s.newStore = func() store.Store {
|
||||
s.newStore = func() (store.Store, error) {
|
||||
s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.Metrics)
|
||||
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(
|
||||
retrylayer.New(s.sqlStore),
|
||||
s.Metrics,
|
||||
s.Cluster,
|
||||
s.CacheProvider,
|
||||
)
|
||||
if err2 != nil {
|
||||
return nil, errors.Wrap(err2, "cannot create local cache layer")
|
||||
}
|
||||
|
||||
searchStore := searchlayer.NewSearchLayer(
|
||||
localcachelayer.NewLocalCacheLayer(
|
||||
retrylayer.New(s.sqlStore),
|
||||
s.Metrics,
|
||||
s.Cluster,
|
||||
s.CacheProvider,
|
||||
),
|
||||
lcl,
|
||||
s.SearchEngine,
|
||||
s.Config(),
|
||||
)
|
||||
@@ -330,17 +348,20 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
return timerlayer.New(
|
||||
searchStore,
|
||||
s.Metrics,
|
||||
)
|
||||
), nil
|
||||
}
|
||||
}
|
||||
|
||||
if htmlTemplateWatcher, err := utils.NewHTMLTemplateWatcher("templates"); err != nil {
|
||||
mlog.Error("Failed to parse server templates", mlog.Err(err))
|
||||
if htmlTemplateWatcher, err2 := utils.NewHTMLTemplateWatcher("templates"); err2 != nil {
|
||||
mlog.Error("Failed to parse server templates", mlog.Err(err2))
|
||||
} else {
|
||||
s.htmlTemplateWatcher = htmlTemplateWatcher
|
||||
}
|
||||
|
||||
s.Store = s.newStore()
|
||||
s.Store, err = s.newStore()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create store")
|
||||
}
|
||||
|
||||
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
|
||||
s.configOrLicenseListener()
|
||||
|
||||
@@ -62,7 +62,11 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
|
||||
options = append(options, app.ConfigStore(memoryStore))
|
||||
if includeCacheLayer {
|
||||
options = append(options, app.StoreOverride(func(s *app.Server) store.Store {
|
||||
return localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
return lcl
|
||||
}))
|
||||
} else {
|
||||
options = append(options, app.StoreOverride(dbStore))
|
||||
|
||||
@@ -43,7 +43,10 @@ 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, err = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
th := &TestHelper{
|
||||
App: app.New(app.ServerConnector(s)),
|
||||
|
||||
24
services/cache/lru.go
поставляемый
24
services/cache/lru.go
поставляемый
@@ -9,21 +9,22 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
|
||||
"github.com/tinylib/msgp/msgp"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
// LRU is a thread-safe fixed size LRU cache.
|
||||
type LRU struct {
|
||||
name string
|
||||
lock sync.RWMutex
|
||||
size int
|
||||
len int
|
||||
currentGeneration int64
|
||||
evictList *list.List
|
||||
items map[string]*list.Element
|
||||
lock sync.RWMutex
|
||||
defaultExpiry time.Duration
|
||||
name string
|
||||
invalidateClusterEvent string
|
||||
currentGeneration int64
|
||||
len int
|
||||
}
|
||||
|
||||
// LRUOptions contains options for initializing LRU cache
|
||||
@@ -32,6 +33,9 @@ type LRUOptions struct {
|
||||
Size int
|
||||
DefaultExpiry time.Duration
|
||||
InvalidateClusterEvent string
|
||||
// StripedBuckets is used only by LRUStriped and shouldn't be greater than the number
|
||||
// of CPUs available on the machine running this cache.
|
||||
StripedBuckets int
|
||||
}
|
||||
|
||||
// entry is used to hold a value in the evictList.
|
||||
@@ -43,7 +47,7 @@ type entry struct {
|
||||
}
|
||||
|
||||
// NewLRU creates an LRU of the given size.
|
||||
func NewLRU(opts *LRUOptions) Cache {
|
||||
func NewLRU(opts LRUOptions) Cache {
|
||||
return &LRU{
|
||||
name: opts.Name,
|
||||
size: opts.Size,
|
||||
@@ -141,19 +145,15 @@ func (l *LRU) set(key string, value interface{}, ttl time.Duration) error {
|
||||
|
||||
var buf []byte
|
||||
var err error
|
||||
|
||||
// We use a fast path for hot structs.
|
||||
if msgpVal, ok := value.(msgp.Marshaler); ok {
|
||||
buf, err = msgpVal.MarshalMsg(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Slow path for other structs.
|
||||
buf, err = msgpack.Marshal(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.lock.Lock()
|
||||
|
||||
149
services/cache/lru_striped.go
поставляемый
Обычный файл
149
services/cache/lru_striped.go
поставляемый
Обычный файл
@@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/cespare/xxhash/v2"
|
||||
)
|
||||
|
||||
// LRUStriped keeps LRU caches in buckets in order to lower mutex contention.
|
||||
// This is achieved by hashing the input key to map it to a dedicated bucket.
|
||||
// Each bucket (an LRU cache) has its own lock that helps distributing the lock
|
||||
// contention on multiple threads/cores, leading to less wait times.
|
||||
//
|
||||
// LRUStriped implements the Cache interface with the same behavior as LRU.
|
||||
//
|
||||
// Note that, because of it's distributed nature, the fixed size cannot be strictly respected
|
||||
// and you may have a tiny bit more space for keys than you defined through LRUOptions.
|
||||
// Bucket size is computed as follows: (size / nbuckets) + (size % nbuckets)
|
||||
//
|
||||
// Because of this size limit per bucket, and because of the nature of the data, you
|
||||
// may have buckets filled unevenly, and because of this, keys will be evicted from the entire
|
||||
// cache where a simple LRU wouldn't have. Example:
|
||||
//
|
||||
// Two buckets B1 and B2, of max size 2 each, meaning, theoretically, a max size of 4:
|
||||
// * Say you have a set of 3 keys, they could fill an entire LRU cache.
|
||||
// * But if all those keys are assigned to a single bucket B1, the first key will be evicted from B1
|
||||
// * B2 will remain empty, even though there was enough memory allocated
|
||||
//
|
||||
// With 4 buckets and random UUIDs as keys, the amount of false evictions is around 5%.
|
||||
//
|
||||
// By default, the number of buckets equals the number of cpus returned from runtime.NumCPU.
|
||||
//
|
||||
// This struct is lock-free and intended to be used without lock.
|
||||
type LRUStriped struct {
|
||||
buckets []*LRU
|
||||
name string
|
||||
invalidateClusterEvent string
|
||||
}
|
||||
|
||||
func (L LRUStriped) hashkeyMapHash(key string) uint64 {
|
||||
return xxhash.Sum64String(key)
|
||||
}
|
||||
|
||||
func (L LRUStriped) keyBucket(key string) *LRU {
|
||||
return L.buckets[L.hashkeyMapHash(key)%uint64(len(L.buckets))]
|
||||
}
|
||||
|
||||
// Purge loops through each LRU cache for purging. Since LRUStriped doesn't use any lock,
|
||||
// each LRU bucket is purged after another one, which means that keys could still
|
||||
// be present after a call to Purge.
|
||||
func (L LRUStriped) Purge() error {
|
||||
for _, lru := range L.buckets {
|
||||
lru.Purge() // errors from purging LRU can be ignored as they always return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set does the same as LRU.Set
|
||||
func (L LRUStriped) Set(key string, value interface{}) error {
|
||||
return L.keyBucket(key).Set(key, value)
|
||||
}
|
||||
|
||||
// SetWithDefaultExpiry does the same as LRU.SetWithDefaultExpiry
|
||||
func (L LRUStriped) SetWithDefaultExpiry(key string, value interface{}) error {
|
||||
return L.keyBucket(key).SetWithDefaultExpiry(key, value)
|
||||
}
|
||||
|
||||
// SetWithExpiry does the same as LRU.SetWithExpiry
|
||||
func (L LRUStriped) SetWithExpiry(key string, value interface{}, ttl time.Duration) error {
|
||||
return L.keyBucket(key).SetWithExpiry(key, value, ttl)
|
||||
}
|
||||
|
||||
// Get does the same as LRU.Get
|
||||
func (L LRUStriped) Get(key string, value interface{}) error {
|
||||
return L.keyBucket(key).Get(key, value)
|
||||
}
|
||||
|
||||
// Remove does the same as LRU.Remove
|
||||
func (L LRUStriped) Remove(key string) error {
|
||||
return L.keyBucket(key).Remove(key)
|
||||
}
|
||||
|
||||
// Keys does the same as LRU.Keys. However, because this is lock-free, keys might be
|
||||
// inserted or removed from a previously scanned LRU cache.
|
||||
// This is not as precise as using a single LRU instance.
|
||||
func (L LRUStriped) Keys() ([]string, error) {
|
||||
var keys []string
|
||||
for _, lru := range L.buckets {
|
||||
k, _ := lru.Keys() // Keys never returns any error
|
||||
keys = append(keys, k...)
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// Len does the same as LRU.Len. As for LRUStriped.Keys, this call cannot be precise.
|
||||
func (L LRUStriped) Len() (int, error) {
|
||||
var size int
|
||||
for _, lru := range L.buckets {
|
||||
s, _ := lru.Len() // Len never returns any error
|
||||
size += s
|
||||
}
|
||||
return size, nil
|
||||
}
|
||||
|
||||
// GetInvalidateClusterEvent does the same as LRU.GetInvalidateClusterEvent
|
||||
func (L LRUStriped) GetInvalidateClusterEvent() string {
|
||||
return L.invalidateClusterEvent
|
||||
}
|
||||
|
||||
// Name does the same as LRU.Name
|
||||
func (L LRUStriped) Name() string {
|
||||
return L.name
|
||||
}
|
||||
|
||||
// NewLRUStriped creates a striped LRU cache using the special LRUOptions.StripedBuckets value.
|
||||
// See LRUStriped and LRUOptions for more details.
|
||||
//
|
||||
// Not that in order to prevent false eviction, this LRU cache adds 10% (computation is rounded up) of the
|
||||
// requested size to the total cache size.
|
||||
func NewLRUStriped(opts LRUOptions) (Cache, error) {
|
||||
if opts.StripedBuckets == 0 {
|
||||
return nil, fmt.Errorf("number of buckets is mandatory")
|
||||
}
|
||||
|
||||
if opts.Size < opts.StripedBuckets {
|
||||
return nil, fmt.Errorf("cache size must at least be equal to the number of buckets")
|
||||
}
|
||||
|
||||
// add 10% to the total size, before splitting
|
||||
opts.Size += int(math.Ceil(float64(opts.Size) * 10.0 / 100.0))
|
||||
// now this is the size for each bucket
|
||||
opts.Size = (opts.Size / opts.StripedBuckets) + (opts.Size % opts.StripedBuckets)
|
||||
|
||||
buckets := make([]*LRU, opts.StripedBuckets)
|
||||
for i := 0; i < opts.StripedBuckets; i++ {
|
||||
buckets[i] = NewLRU(opts).(*LRU)
|
||||
}
|
||||
|
||||
return LRUStriped{
|
||||
buckets: buckets,
|
||||
invalidateClusterEvent: opts.InvalidateClusterEvent,
|
||||
name: opts.Name,
|
||||
}, nil
|
||||
}
|
||||
91
services/cache/lru_striped_bench_test.go
поставляемый
Обычный файл
91
services/cache/lru_striped_bench_test.go
поставляемый
Обычный файл
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package cache_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/services/cache"
|
||||
|
||||
"github.com/cespare/xxhash/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
m = 500_000
|
||||
)
|
||||
|
||||
func BenchmarkLRUStriped(b *testing.B) {
|
||||
opts := cache.LRUOptions{
|
||||
Name: "",
|
||||
Size: 128,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}
|
||||
|
||||
cache, err := cache.NewLRUStriped(opts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// prepare keys and initial cache values and set routine
|
||||
keys := make([]string, 0, m)
|
||||
// bucketKeys is to demonstrate that splitted locks is working correctly
|
||||
// by assigning one sequence of key for each bucket.
|
||||
bucketKeys := make([][]string, opts.StripedBuckets)
|
||||
for i := 0; i < m; i++ {
|
||||
key := fmt.Sprintf("%d-key-%d", i, i)
|
||||
keys = append(keys, key)
|
||||
bucketKey := xxhash.Sum64String(key) % uint64(opts.StripedBuckets)
|
||||
bucketKeys[bucketKey] = append(bucketKeys[bucketKey], key)
|
||||
}
|
||||
for i := 0; i < opts.Size; i++ {
|
||||
cache.Set(keys[i], "preflight")
|
||||
}
|
||||
|
||||
wgGet := &sync.WaitGroup{}
|
||||
wgSet := &sync.WaitGroup{}
|
||||
// need buffered chan because if the set routine finished before we write into the chan,
|
||||
// we're left without any consumer, making any write to the chan waiting forever.
|
||||
stopSet := make(chan bool, 1)
|
||||
set := func() {
|
||||
defer wgSet.Done()
|
||||
for i := 0; i < m; i++ {
|
||||
select {
|
||||
case <-stopSet:
|
||||
return
|
||||
default:
|
||||
_ = cache.Set(keys[i], "ignored")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get := func(bucket int) {
|
||||
defer wgGet.Done()
|
||||
var out string
|
||||
for i := 0; i < m; i++ {
|
||||
_ = cache.Get(bucketKeys[bucket][i%opts.Size], &out)
|
||||
}
|
||||
}
|
||||
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
wgSet.Add(1)
|
||||
go set()
|
||||
for j := 0; j < opts.StripedBuckets; j++ {
|
||||
wgGet.Add(1)
|
||||
go get(j)
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
wgGet.Wait()
|
||||
b.StopTimer()
|
||||
|
||||
stopSet <- true
|
||||
wgSet.Wait()
|
||||
}
|
||||
}
|
||||
129
services/cache/lru_striped_test.go
поставляемый
Обычный файл
129
services/cache/lru_striped_test.go
поставляемый
Обычный файл
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/maphash"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
|
||||
"github.com/cespare/xxhash/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func makeLRUPredictibleTestData(num int) [][2]string {
|
||||
kv := make([][2]string, num)
|
||||
for i := 0; i < len(kv); i++ {
|
||||
kv[i] = [2]string{
|
||||
fmt.Sprintf("%d-key-%d", i, i),
|
||||
fmt.Sprintf("%d-val-%d", i, i),
|
||||
}
|
||||
}
|
||||
return kv
|
||||
}
|
||||
|
||||
func TestNewLRUStriped(t *testing.T) {
|
||||
scache, err := NewLRUStriped(LRUOptions{StripedBuckets: 3, Size: 20})
|
||||
require.NoError(t, err)
|
||||
|
||||
cache := scache.(LRUStriped)
|
||||
|
||||
require.Len(t, cache.buckets, 3)
|
||||
assert.Equal(t, 8, cache.buckets[0].size)
|
||||
assert.Equal(t, 8, cache.buckets[1].size)
|
||||
assert.Equal(t, 8, cache.buckets[2].size)
|
||||
}
|
||||
|
||||
func TestLRUStripedKeyDistribution(t *testing.T) {
|
||||
dataset := makeLRUPredictibleTestData(100)
|
||||
|
||||
scache, err := NewLRUStriped(LRUOptions{StripedBuckets: 4, Size: len(dataset)})
|
||||
require.NoError(t, err)
|
||||
cache := scache.(LRUStriped)
|
||||
for _, kv := range dataset {
|
||||
require.NoError(t, cache.Set(kv[0], kv[1]))
|
||||
var out string
|
||||
require.NoError(t, cache.Get(kv[0], &out))
|
||||
require.Equal(t, kv[1], out)
|
||||
}
|
||||
|
||||
require.Len(t, cache.buckets, 4)
|
||||
acc := 0
|
||||
for i := 0; i < 4; i++ {
|
||||
clen, err := cache.buckets[i].Len()
|
||||
acc += clen
|
||||
assert.NoError(t, err)
|
||||
assert.GreaterOrEqual(t, clen, len(dataset)/2/4, "at least 50%/nbuckets of all keys in each bucket")
|
||||
}
|
||||
// because of the limited size of each bucket and the nature of our data,
|
||||
// we may have around 10% of our keys evicted in this scenario. removing 1% because we cannot predict
|
||||
// accurately what is happening with random data.
|
||||
assert.GreaterOrEqual(t, acc, len(dataset)-(len(dataset)*1.0/100.0))
|
||||
}
|
||||
|
||||
func TestLRUStriped_Size(t *testing.T) {
|
||||
scache, err := NewLRUStriped(LRUOptions{StripedBuckets: 2, Size: 128})
|
||||
require.NoError(t, err)
|
||||
cache := scache.(LRUStriped)
|
||||
acc := 0
|
||||
for _, bucket := range cache.buckets {
|
||||
acc += bucket.size
|
||||
}
|
||||
assert.Equal(t, 128+13+1, acc) // +10% +modulo padding
|
||||
}
|
||||
|
||||
func TestLRUStriped_HashKey(t *testing.T) {
|
||||
scache, err := NewLRUStriped(LRUOptions{StripedBuckets: 2, Size: 128})
|
||||
require.NoError(t, err)
|
||||
cache := scache.(LRUStriped)
|
||||
first := cache.hashkeyMapHash("key")
|
||||
cache.hashkeyMapHash("other_key_to_ensure_that_result_it’s_not_dependent_on_previous_input")
|
||||
second := cache.hashkeyMapHash("key")
|
||||
require.Equal(t, first, second)
|
||||
}
|
||||
|
||||
func TestLRUStriped_Get(t *testing.T) {
|
||||
cache, err := NewLRUStriped(LRUOptions{StripedBuckets: 4, Size: 128})
|
||||
require.NoError(t, err)
|
||||
var out string
|
||||
require.Equal(t, ErrKeyNotFound, cache.Get("key", &out))
|
||||
require.Zero(t, out)
|
||||
|
||||
require.NoError(t, cache.Set("key", "value"))
|
||||
require.NoError(t, cache.Get("key", &out))
|
||||
require.Equal(t, "value", out)
|
||||
}
|
||||
|
||||
var hashSink uint64
|
||||
|
||||
func BenchmarkSum64(b *testing.B) {
|
||||
cases := []string{
|
||||
"1",
|
||||
"22",
|
||||
"333",
|
||||
model.NewId(),
|
||||
model.NewId() + model.NewId(),
|
||||
}
|
||||
|
||||
for _, case_ := range cases {
|
||||
b.Run(fmt.Sprintf("maphash_string_len_%d", len(case_)), func(b *testing.B) {
|
||||
seed := maphash.MakeSeed()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var h maphash.Hash
|
||||
h.SetSeed(seed)
|
||||
h.WriteString(case_) // documentation and code says it never fails
|
||||
hashSink = h.Sum64()
|
||||
}
|
||||
})
|
||||
b.Run(fmt.Sprintf("xxhash_string_len_%d", len(case_)), func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
hashSink = xxhash.Sum64String(case_)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
22
services/cache/lru_test.go
поставляемый
22
services/cache/lru_test.go
поставляемый
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func TestLRU(t *testing.T) {
|
||||
l := NewLRU(&LRUOptions{
|
||||
l := NewLRU(LRUOptions{
|
||||
Size: 128,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -83,7 +83,7 @@ func TestLRU(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLRUExpire(t *testing.T) {
|
||||
l := NewLRU(&LRUOptions{
|
||||
l := NewLRU(LRUOptions{
|
||||
Size: 128,
|
||||
DefaultExpiry: 1 * time.Second,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -105,7 +105,7 @@ func TestLRUExpire(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLRUMarshalUnMarshal(t *testing.T) {
|
||||
l := NewLRU(&LRUOptions{
|
||||
l := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -299,7 +299,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("simple=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -349,7 +349,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("complex=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -432,7 +432,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("User=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -465,7 +465,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("UserMap=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -545,7 +545,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("Post=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -569,7 +569,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("Status=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -605,7 +605,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
|
||||
b.Run("Session=new", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
@@ -621,7 +621,7 @@ func BenchmarkLRU(b *testing.B) {
|
||||
}
|
||||
|
||||
func TestLRURace(t *testing.T) {
|
||||
l2 := NewLRU(&LRUOptions{
|
||||
l2 := NewLRU(LRUOptions{
|
||||
Size: 1,
|
||||
DefaultExpiry: 0,
|
||||
InvalidateClusterEvent: "",
|
||||
|
||||
7
services/cache/mocks/Cache.go
поставляемый
7
services/cache/mocks/Cache.go
поставляемый
@@ -2,8 +2,11 @@
|
||||
|
||||
package mocks
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import time "time"
|
||||
import (
|
||||
time "time"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// Cache is an autogenerated mock type for the Cache type
|
||||
type Cache struct {
|
||||
|
||||
11
services/cache/mocks/Provider.go
поставляемый
11
services/cache/mocks/Provider.go
поставляемый
@@ -41,7 +41,7 @@ func (_m *Provider) Connect() error {
|
||||
}
|
||||
|
||||
// NewCache provides a mock function with given fields: opts
|
||||
func (_m *Provider) NewCache(opts *cache.CacheOptions) cache.Cache {
|
||||
func (_m *Provider) NewCache(opts *cache.CacheOptions) (cache.Cache, error) {
|
||||
ret := _m.Called(opts)
|
||||
|
||||
var r0 cache.Cache
|
||||
@@ -53,5 +53,12 @@ func (_m *Provider) NewCache(opts *cache.CacheOptions) cache.Cache {
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*cache.CacheOptions) error); ok {
|
||||
r1 = rf(opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
19
services/cache/provider.go
поставляемый
19
services/cache/provider.go
поставляемый
@@ -11,12 +11,14 @@ type CacheOptions struct {
|
||||
DefaultExpiry time.Duration
|
||||
Name string
|
||||
InvalidateClusterEvent string
|
||||
Striped bool
|
||||
StripedBuckets int
|
||||
}
|
||||
|
||||
// Provider is a provider for Cache
|
||||
type Provider interface {
|
||||
// NewCache creates a new cache with given options.
|
||||
NewCache(opts *CacheOptions) Cache
|
||||
NewCache(opts *CacheOptions) (Cache, error)
|
||||
// Connect opens a new connection to the cache using specific provider parameters.
|
||||
Connect() error
|
||||
// Close releases any resources used by the cache provider.
|
||||
@@ -32,13 +34,22 @@ func NewProvider() Provider {
|
||||
}
|
||||
|
||||
// NewCache creates a new cache with given opts
|
||||
func (c *cacheProvider) NewCache(opts *CacheOptions) Cache {
|
||||
return NewLRU(&LRUOptions{
|
||||
func (c *cacheProvider) NewCache(opts *CacheOptions) (Cache, error) {
|
||||
if opts.Striped {
|
||||
return NewLRUStriped(LRUOptions{
|
||||
Name: opts.Name,
|
||||
Size: opts.Size,
|
||||
DefaultExpiry: opts.DefaultExpiry,
|
||||
InvalidateClusterEvent: opts.InvalidateClusterEvent,
|
||||
StripedBuckets: opts.StripedBuckets,
|
||||
})
|
||||
}
|
||||
return NewLRU(LRUOptions{
|
||||
Name: opts.Name,
|
||||
Size: opts.Size,
|
||||
DefaultExpiry: opts.DefaultExpiry,
|
||||
InvalidateClusterEvent: opts.InvalidateClusterEvent,
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
|
||||
// Connect opens a new connection to the cache using specific provider parameters.
|
||||
|
||||
133
services/cache/provider_test.go
поставляемый
133
services/cache/provider_test.go
поставляемый
@@ -15,16 +15,39 @@ func TestNewCache(t *testing.T) {
|
||||
p := NewProvider()
|
||||
|
||||
size := 1
|
||||
c := p.NewCache(&CacheOptions{
|
||||
c, err := p.NewCache(&CacheOptions{
|
||||
Size: size,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err := c.Set("key1", "val1")
|
||||
require.Nil(t, err)
|
||||
err = c.Set("key1", "val1")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key2", "val2")
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key3", "val3")
|
||||
require.NoError(t, err)
|
||||
l, err := c.Len()
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, size, l)
|
||||
})
|
||||
|
||||
t.Run("with only size option given", func(t *testing.T) {
|
||||
p := NewProvider()
|
||||
|
||||
size := 1
|
||||
c, err := p.NewCache(&CacheOptions{
|
||||
Size: size,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = c.Set("key1", "val1")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key2", "val2")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key3", "val3")
|
||||
require.NoError(t, err)
|
||||
l, err := c.Len()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, size, l)
|
||||
})
|
||||
|
||||
@@ -34,21 +57,24 @@ func TestNewCache(t *testing.T) {
|
||||
size := 1
|
||||
expiry := 1 * time.Second
|
||||
event := "clusterEvent"
|
||||
c := p.NewCache(&CacheOptions{
|
||||
c, err := p.NewCache(&CacheOptions{
|
||||
Size: size,
|
||||
Name: "name",
|
||||
DefaultExpiry: expiry,
|
||||
InvalidateClusterEvent: event,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, event, c.GetInvalidateClusterEvent())
|
||||
|
||||
err := c.SetWithDefaultExpiry("key1", "val1")
|
||||
require.Nil(t, err)
|
||||
err = c.SetWithDefaultExpiry("key1", "val1")
|
||||
require.NoError(t, err)
|
||||
err = c.SetWithDefaultExpiry("key2", "val2")
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
err = c.SetWithDefaultExpiry("key3", "val3")
|
||||
require.NoError(t, err)
|
||||
l, err := c.Len()
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, size, l)
|
||||
|
||||
time.Sleep(expiry + 1*time.Second)
|
||||
@@ -58,6 +84,93 @@ func TestNewCache(t *testing.T) {
|
||||
require.Equal(t, ErrKeyNotFound, err)
|
||||
err = c.Get("key2", &v)
|
||||
require.Equal(t, ErrKeyNotFound, err)
|
||||
err = c.Get("key3", &v)
|
||||
require.Equal(t, ErrKeyNotFound, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewCache_Striped(t *testing.T) {
|
||||
t.Run("with only size option given", func(t *testing.T) {
|
||||
p := NewProvider()
|
||||
|
||||
size := 1
|
||||
c, err := p.NewCache(&CacheOptions{
|
||||
Size: size,
|
||||
Striped: true,
|
||||
StripedBuckets: 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = c.Set("key1", "val1")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key2", "val2")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key3", "val3")
|
||||
require.NoError(t, err)
|
||||
l, err := c.Len()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, size+1, l) // +10% from striping
|
||||
})
|
||||
|
||||
t.Run("with only size option given", func(t *testing.T) {
|
||||
p := NewProvider()
|
||||
|
||||
size := 1
|
||||
c, err := p.NewCache(&CacheOptions{
|
||||
Size: size,
|
||||
Striped: true,
|
||||
StripedBuckets: 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = c.Set("key1", "val1")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key2", "val2")
|
||||
require.NoError(t, err)
|
||||
err = c.Set("key3", "val3")
|
||||
require.NoError(t, err)
|
||||
l, err := c.Len()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, size+1, l) // +10% rounded up from striped lru
|
||||
})
|
||||
|
||||
t.Run("with all options specified", func(t *testing.T) {
|
||||
p := NewProvider()
|
||||
|
||||
size := 1
|
||||
expiry := 1 * time.Second
|
||||
event := "clusterEvent"
|
||||
c, err := p.NewCache(&CacheOptions{
|
||||
Size: size,
|
||||
Name: "name",
|
||||
DefaultExpiry: expiry,
|
||||
InvalidateClusterEvent: event,
|
||||
Striped: true,
|
||||
StripedBuckets: 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, event, c.GetInvalidateClusterEvent())
|
||||
|
||||
err = c.SetWithDefaultExpiry("key1", "val1")
|
||||
require.NoError(t, err)
|
||||
err = c.SetWithDefaultExpiry("key2", "val2")
|
||||
require.NoError(t, err)
|
||||
err = c.SetWithDefaultExpiry("key3", "val3")
|
||||
require.NoError(t, err)
|
||||
l, err := c.Len()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, size+1, l) // +10% from striping
|
||||
|
||||
time.Sleep(expiry + 1*time.Second)
|
||||
|
||||
var v string
|
||||
err = c.Get("key1", &v)
|
||||
require.Equal(t, ErrKeyNotFound, err)
|
||||
err = c.Get("key2", &v)
|
||||
require.Equal(t, ErrKeyNotFound, err)
|
||||
err = c.Get("key3", &v)
|
||||
require.Equal(t, ErrKeyNotFound, err)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
count, err := cachedStore.Channel().GetMemberCount("id", true)
|
||||
require.Nil(t, err)
|
||||
@@ -40,7 +41,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetMemberCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
|
||||
@@ -51,7 +53,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
|
||||
t.Run("first call force not cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetMemberCount("id", false)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
|
||||
@@ -64,7 +67,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
|
||||
t.Run("first call with GetMemberCountFromCache not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
count := cachedStore.Channel().GetMemberCountFromCache("id")
|
||||
assert.Equal(t, count, countResult)
|
||||
@@ -77,7 +81,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetMemberCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
|
||||
@@ -89,7 +94,8 @@ func TestChannelStoreChannelMemberCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetMemberCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMemberCount", 1)
|
||||
@@ -105,7 +111,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
count, err := cachedStore.Channel().GetPinnedPostCount("id", true)
|
||||
require.Nil(t, err)
|
||||
@@ -120,7 +127,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetPinnedPostCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
|
||||
@@ -131,7 +139,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
|
||||
t.Run("first call force not cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetPinnedPostCount("id", false)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
|
||||
@@ -144,7 +153,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetPinnedPostCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
|
||||
@@ -156,7 +166,8 @@ func TestChannelStoreChannelPinnedPostsCountsCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetPinnedPostCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetPinnedPostCount", 1)
|
||||
@@ -172,7 +183,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
count, err := cachedStore.Channel().GetGuestCount("id", true)
|
||||
require.Nil(t, err)
|
||||
@@ -187,7 +199,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetGuestCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
|
||||
@@ -198,7 +211,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
|
||||
t.Run("first call force not cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetGuestCount("id", false)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
|
||||
@@ -211,7 +225,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
|
||||
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetGuestCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
|
||||
@@ -223,7 +238,8 @@ func TestChannelStoreGuestCountCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().GetGuestCount("id", true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetGuestCount", 1)
|
||||
@@ -239,7 +255,8 @@ func TestChannelStoreChannel(t *testing.T) {
|
||||
t.Run("first call by id not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
channel, err := cachedStore.Channel().Get(channelId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -254,7 +271,8 @@ func TestChannelStoreChannel(t *testing.T) {
|
||||
t.Run("first call not cached, second force no cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().Get(channelId, true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -265,7 +283,8 @@ func TestChannelStoreChannel(t *testing.T) {
|
||||
t.Run("first call force no cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
cachedStore.Channel().Get(channelId, false)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
cachedStore.Channel().Get(channelId, true)
|
||||
@@ -277,7 +296,8 @@ func TestChannelStoreChannel(t *testing.T) {
|
||||
t.Run("first call not cached, clear cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Channel().Get(channelId, true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -289,7 +309,8 @@ func TestChannelStoreChannel(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate cache, second call not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
cachedStore.Channel().Get(channelId, true)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
cachedStore.Channel().InvalidateChannel(channelId)
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by id not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
emoji, err := cachedStore.Emoji().Get("123", true)
|
||||
require.Nil(t, err)
|
||||
@@ -38,7 +39,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by name not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
emoji, err := cachedStore.Emoji().GetByName("name123", true)
|
||||
require.Nil(t, err)
|
||||
@@ -53,7 +55,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by id not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().Get("123", true)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -64,7 +67,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by name not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().GetByName("name123", true)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
@@ -75,7 +79,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by id force not cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().Get("123", false)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -88,7 +93,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by name force not cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().GetByName("name123", false)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
@@ -101,7 +107,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by id, second call by name cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().Get("123", true)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -112,7 +119,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by name, second call by id cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().GetByName("name123", true)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
@@ -123,7 +131,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by id not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().Get("123", true)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -135,7 +144,8 @@ func TestEmojiStoreCache(t *testing.T) {
|
||||
t.Run("first call by name not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Emoji().GetByName("name123", true)
|
||||
mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestFileInfoStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
fileInfos, err := cachedStore.FileInfo().GetForPost("123", true, true, true)
|
||||
require.Nil(t, err)
|
||||
@@ -37,7 +38,8 @@ func TestFileInfoStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force no cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.FileInfo().GetForPost("123", true, true, true)
|
||||
mockStore.FileInfo().(*mocks.FileInfoStore).AssertNumberOfCalls(t, "GetForPost", 1)
|
||||
@@ -48,7 +50,8 @@ func TestFileInfoStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.FileInfo().GetForPost("123", true, true, true)
|
||||
mockStore.FileInfo().(*mocks.FileInfoStore).AssertNumberOfCalls(t, "GetForPost", 1)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package localcachelayer
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/einterfaces"
|
||||
@@ -108,152 +109,191 @@ type LocalCacheStore struct {
|
||||
termsOfServiceCache cache.Cache
|
||||
}
|
||||
|
||||
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider) LocalCacheStore {
|
||||
|
||||
localCacheStore := LocalCacheStore{
|
||||
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider) (localCacheStore LocalCacheStore, err error) {
|
||||
localCacheStore = LocalCacheStore{
|
||||
Store: baseStore,
|
||||
cluster: cluster,
|
||||
metrics: metrics,
|
||||
}
|
||||
// Reactions
|
||||
localCacheStore.reactionCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.reactionCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: REACTION_CACHE_SIZE,
|
||||
Name: "Reaction",
|
||||
DefaultExpiry: REACTION_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
|
||||
|
||||
// Roles
|
||||
localCacheStore.roleCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.roleCache, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
Striped: true,
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.rolePermissionsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ROLE_CACHE_SIZE,
|
||||
Name: "RolePermission",
|
||||
DefaultExpiry: ROLE_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
|
||||
|
||||
// Schemes
|
||||
localCacheStore.schemeCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.schemeCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: SCHEME_CACHE_SIZE,
|
||||
Name: "Scheme",
|
||||
DefaultExpiry: SCHEME_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
|
||||
|
||||
// FileInfo
|
||||
localCacheStore.fileInfoCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.fileInfoCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: FILE_INFO_CACHE_SIZE,
|
||||
Name: "FileInfo",
|
||||
DefaultExpiry: FILE_INFO_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_FILE_INFOS,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.fileInfo = LocalCacheFileInfoStore{FileInfoStore: baseStore.FileInfo(), rootStore: &localCacheStore}
|
||||
|
||||
// Webhooks
|
||||
localCacheStore.webhookCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.webhookCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: WEBHOOK_CACHE_SIZE,
|
||||
Name: "Webhook",
|
||||
DefaultExpiry: WEBHOOK_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
|
||||
|
||||
// Emojis
|
||||
localCacheStore.emojiCacheById = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.emojiCacheById, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.emojiIdCacheByName, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: EMOJI_CACHE_SIZE,
|
||||
Name: "EmojiByName",
|
||||
DefaultExpiry: EMOJI_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.emoji = LocalCacheEmojiStore{EmojiStore: baseStore.Emoji(), rootStore: &localCacheStore}
|
||||
|
||||
// Channels
|
||||
localCacheStore.channelPinnedPostCountsCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.channelPinnedPostCountsCache, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelMemberCountsCache, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelGuestCountCache, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelByIdCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.CHANNEL_CACHE_SIZE,
|
||||
Name: "channelById",
|
||||
DefaultExpiry: CHANNEL_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.channel = LocalCacheChannelStore{ChannelStore: baseStore.Channel(), rootStore: &localCacheStore}
|
||||
|
||||
// Posts
|
||||
localCacheStore.postLastPostsCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.postLastPostsCache, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.lastPostTimeCache, err = cacheProvider.NewCache(&cache.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,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
|
||||
|
||||
// TOS
|
||||
localCacheStore.termsOfServiceCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.termsOfServiceCache, err = cacheProvider.NewCache(&cache.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,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
|
||||
|
||||
// Users
|
||||
localCacheStore.userProfileByIdsCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.userProfileByIdsCache, err = cacheProvider.NewCache(&cache.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(&cache.CacheOptions{
|
||||
Striped: true,
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.profilesInChannelCache, err = cacheProvider.NewCache(&cache.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,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.user = LocalCacheUserStore{UserStore: baseStore.User(), rootStore: &localCacheStore}
|
||||
|
||||
// Teams
|
||||
localCacheStore.teamAllTeamIdsForUserCache = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
if localCacheStore.teamAllTeamIdsForUserCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: TEAM_CACHE_SIZE,
|
||||
Name: "Team",
|
||||
DefaultExpiry: TEAM_CACHE_SEC * time.Second,
|
||||
InvalidateClusterEvent: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.team = LocalCacheTeamStore{TeamStore: baseStore.Team(), rootStore: &localCacheStore}
|
||||
|
||||
if cluster != nil {
|
||||
@@ -276,7 +316,7 @@ func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterf
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL, localCacheStore.user.handleClusterInvalidateProfilesInChannel)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS, localCacheStore.team.handleClusterInvalidateTeam)
|
||||
}
|
||||
return localCacheStore
|
||||
return
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Reaction() store.ReactionStore {
|
||||
|
||||
@@ -96,9 +96,13 @@ func initStores() {
|
||||
st := st
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
var err error
|
||||
defer wg.Done()
|
||||
st.SqlStore = sqlstore.New(*st.SqlSettings, nil)
|
||||
st.Store = NewLocalCacheLayer(st.SqlStore, nil, nil, getMockCacheProvider())
|
||||
st.Store, err = NewLocalCacheLayer(st.SqlStore, nil, nil, getMockCacheProvider())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
st.Store.DropAllTables()
|
||||
st.Store.MarkSystemRanUnitTests()
|
||||
}()
|
||||
|
||||
@@ -23,7 +23,7 @@ var mainHelper *testlib.MainHelper
|
||||
func getMockCacheProvider() cache.Provider {
|
||||
mockCacheProvider := cachemocks.Provider{}
|
||||
mockCacheProvider.On("NewCache", mock.Anything).
|
||||
Return(cache.NewLRU(&cache.LRUOptions{Size: 128}))
|
||||
Return(cache.NewLRU(cache.LRUOptions{Size: 128}), nil)
|
||||
return &mockCacheProvider
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetEtag: first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedResult := fmt.Sprintf("%v.%v", model.CurrentVersion, fakeLastTime)
|
||||
|
||||
@@ -46,7 +47,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetEtag: first call not cached, second force no cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Post().GetEtag(channelId, true)
|
||||
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetEtag", 1)
|
||||
@@ -57,7 +59,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetEtag: first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Post().GetEtag(channelId, true)
|
||||
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetEtag", 1)
|
||||
@@ -69,7 +72,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetEtag: first call not cached, clear caches, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Post().GetEtag(channelId, true)
|
||||
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetEtag", 1)
|
||||
@@ -81,7 +85,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetPostsSince: first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedResult := model.NewPostList()
|
||||
|
||||
@@ -99,7 +104,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetPostsSince: first call not cached, second force no cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Post().GetPostsSince(fakeOptions, true)
|
||||
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetPostsSince", 1)
|
||||
@@ -110,7 +116,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetPostsSince: first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Post().GetPostsSince(fakeOptions, true)
|
||||
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetPostsSince", 1)
|
||||
@@ -122,7 +129,8 @@ func TestPostStoreLastPostTimeCache(t *testing.T) {
|
||||
t.Run("GetPostsSince: first call not cached, clear caches, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Post().GetPostsSince(fakeOptions, true)
|
||||
mockStore.Post().(*mocks.PostStore).AssertNumberOfCalls(t, "GetPostsSince", 1)
|
||||
@@ -139,7 +147,8 @@ func TestPostStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotPosts, err := cachedStore.Post().GetPosts(fakeOptions, true)
|
||||
require.Nil(t, err)
|
||||
@@ -153,7 +162,8 @@ func TestPostStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotPosts, err := cachedStore.Post().GetPosts(fakeOptions, true)
|
||||
require.Nil(t, err)
|
||||
@@ -167,7 +177,8 @@ func TestPostStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotPosts, err := cachedStore.Post().GetPosts(fakeOptions, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestReactionStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
reaction, err := cachedStore.Reaction().GetForPost("123", true)
|
||||
require.Nil(t, err)
|
||||
@@ -38,7 +39,8 @@ func TestReactionStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Reaction().GetForPost("123", true)
|
||||
mockStore.Reaction().(*mocks.ReactionStore).AssertNumberOfCalls(t, "GetForPost", 1)
|
||||
@@ -49,7 +51,8 @@ func TestReactionStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, save, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Reaction().GetForPost("123", true)
|
||||
mockStore.Reaction().(*mocks.ReactionStore).AssertNumberOfCalls(t, "GetForPost", 1)
|
||||
@@ -61,7 +64,8 @@ func TestReactionStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, delete, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Reaction().GetForPost("123", true)
|
||||
mockStore.Reaction().(*mocks.ReactionStore).AssertNumberOfCalls(t, "GetForPost", 1)
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestRoleStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
role, err := cachedStore.Role().GetByName("role-name")
|
||||
require.Nil(t, err)
|
||||
@@ -38,7 +39,8 @@ func TestRoleStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, save, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Role().GetByName("role-name")
|
||||
mockStore.Role().(*mocks.RoleStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
@@ -50,7 +52,8 @@ func TestRoleStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, delete, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Role().GetByName("role-name")
|
||||
mockStore.Role().(*mocks.RoleStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
@@ -62,7 +65,8 @@ func TestRoleStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, permanent delete all, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Role().GetByName("role-name")
|
||||
mockStore.Role().(*mocks.RoleStore).AssertNumberOfCalls(t, "GetByName", 1)
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestSchemeStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
scheme, err := cachedStore.Scheme().Get("123")
|
||||
require.Nil(t, err)
|
||||
@@ -38,7 +39,8 @@ func TestSchemeStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, save, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Scheme().Get("123")
|
||||
mockStore.Scheme().(*mocks.SchemeStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -50,7 +52,8 @@ func TestSchemeStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, delete, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Scheme().Get("123")
|
||||
mockStore.Scheme().(*mocks.SchemeStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -62,7 +65,8 @@ func TestSchemeStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, permanent delete all, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Scheme().Get("123")
|
||||
mockStore.Scheme().(*mocks.SchemeStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestTeamStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUserTeamIds, err := cachedStore.Team().GetUserTeamIds(fakeUserId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -39,7 +40,8 @@ func TestTeamStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUserTeamIds, err := cachedStore.Team().GetUserTeamIds(fakeUserId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -55,7 +57,8 @@ func TestTeamStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUserTeamIds, err := cachedStore.Team().GetUserTeamIds(fakeUserId, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -24,7 +24,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call by latest not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
termsOfService, err := cachedStore.TermsOfService().GetLatest(true)
|
||||
require.Nil(t, err)
|
||||
@@ -39,7 +40,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call by id not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
termsOfService, err := cachedStore.TermsOfService().Get("123", true)
|
||||
require.Nil(t, err)
|
||||
@@ -54,7 +56,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call by id not cached, second force no cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().Get("123", true)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -65,7 +68,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call latest not cached, second force no cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().GetLatest(true)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
|
||||
@@ -76,7 +80,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call by id force no cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().Get("123", false)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -89,7 +94,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call latest force no cached, second not cached, third cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().GetLatest(false)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
|
||||
@@ -102,7 +108,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call latest, second call by id cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().GetLatest(true)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
|
||||
@@ -113,7 +120,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first call by id not cached, save, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().Get("123", false)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "Get", 1)
|
||||
@@ -125,7 +133,8 @@ func TestTermsOfServiceStoreTermsOfServiceCache(t *testing.T) {
|
||||
t.Run("first get latest not cached, save new, then get latest, returning different data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.TermsOfService().GetLatest(true)
|
||||
mockStore.TermsOfService().(*mocks.TermsOfServiceStore).AssertNumberOfCalls(t, "GetLatest", 1)
|
||||
|
||||
@@ -30,7 +30,8 @@ func TestUserStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUser, err := cachedStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, true)
|
||||
require.Nil(t, err)
|
||||
@@ -44,7 +45,8 @@ func TestUserStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUser, err := cachedStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, true)
|
||||
require.Nil(t, err)
|
||||
@@ -58,7 +60,8 @@ func TestUserStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUser, err := cachedStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, true)
|
||||
require.Nil(t, err)
|
||||
@@ -73,7 +76,8 @@ func TestUserStoreCache(t *testing.T) {
|
||||
t.Run("should always return a copy of the stored data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
storedUsers, err := mockStore.User().GetProfileByIds(fakeUserIds, &store.UserGetByIdsOpts{}, false)
|
||||
require.Nil(t, err)
|
||||
@@ -122,7 +126,8 @@ func TestUserStoreProfilesInChannelCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotMap, err := cachedStore.User().GetAllProfilesInChannel(fakeChannelId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -136,7 +141,8 @@ func TestUserStoreProfilesInChannelCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotMap, err := cachedStore.User().GetAllProfilesInChannel(fakeChannelId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -150,7 +156,8 @@ func TestUserStoreProfilesInChannelCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate by channel, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotMap, err := cachedStore.User().GetAllProfilesInChannel(fakeChannelId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -166,7 +173,8 @@ func TestUserStoreProfilesInChannelCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate by user, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotMap, err := cachedStore.User().GetAllProfilesInChannel(fakeChannelId, true)
|
||||
require.Nil(t, err)
|
||||
@@ -190,7 +198,8 @@ func TestUserStoreGetCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUser, err := cachedStore.User().Get(fakeUserId)
|
||||
require.Nil(t, err)
|
||||
@@ -204,7 +213,8 @@ func TestUserStoreGetCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotUser, err := cachedStore.User().Get(fakeUserId)
|
||||
require.Nil(t, err)
|
||||
@@ -220,7 +230,8 @@ func TestUserStoreGetCache(t *testing.T) {
|
||||
t.Run("should always return a copy of the stored data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
storedUser, err := mockStore.User().Get(fakeUserId)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -24,7 +24,8 @@ func TestWebhookStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
incomingWebhook, err := cachedStore.Webhook().GetIncoming("123", true)
|
||||
require.Nil(t, err)
|
||||
@@ -39,7 +40,8 @@ func TestWebhookStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, second force not cached", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Webhook().GetIncoming("123", true)
|
||||
mockStore.Webhook().(*mocks.WebhookStore).AssertNumberOfCalls(t, "GetIncoming", 1)
|
||||
@@ -50,7 +52,8 @@ func TestWebhookStoreCache(t *testing.T) {
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
cachedStore, err := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
require.NoError(t, err)
|
||||
|
||||
cachedStore.Webhook().GetIncoming("123", true)
|
||||
mockStore.Webhook().(*mocks.WebhookStore).AssertNumberOfCalls(t, "GetIncoming", 1)
|
||||
|
||||
@@ -334,13 +334,13 @@ type publicChannel struct {
|
||||
Purpose string `json:"purpose"`
|
||||
}
|
||||
|
||||
var allChannelMembersForUserCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var allChannelMembersForUserCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE,
|
||||
})
|
||||
var allChannelMembersNotifyPropsForChannelCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var allChannelMembersNotifyPropsForChannelCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: ALL_CHANNEL_MEMBERS_NOTIFY_PROPS_FOR_CHANNEL_CACHE_SIZE,
|
||||
})
|
||||
var channelByNameCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var channelByNameCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: model.CHANNEL_CACHE_SIZE,
|
||||
})
|
||||
|
||||
|
||||
@@ -85,7 +85,10 @@ 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, err = localcachelayer.NewLocalCacheLayer(s.Store, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
prevListenAddress := *s.Config().ServiceSettings.ListenAddress
|
||||
|
||||
Ссылка в новой задаче
Block a user