From 487bb56a9b8f5c7a9efaabfc631f2f6c689ef74b Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Tue, 7 Feb 2017 12:36:37 -0800 Subject: Add caching for file infos (#5330) --- store/sql_file_info_store.go | 43 ++++++++++++++++++++++++++++++++++++++- store/sql_file_info_store_test.go | 12 ++++++++--- store/store.go | 3 ++- 3 files changed, 53 insertions(+), 5 deletions(-) (limited to 'store') diff --git a/store/sql_file_info_store.go b/store/sql_file_info_store.go index 762eac5d4..b1ad4b11a 100644 --- a/store/sql_file_info_store.go +++ b/store/sql_file_info_store.go @@ -3,13 +3,26 @@ package store import ( + "github.com/mattermost/platform/einterfaces" "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" ) type SqlFileInfoStore struct { *SqlStore } +const ( + FILE_INFO_CACHE_SIZE = 25000 + FILE_INFO_CACHE_SEC = 900 // 15 minutes +) + +var fileInfoCache *utils.Cache = utils.NewLru(FILE_INFO_CACHE_SIZE) + +func ClearFileCaches() { + fileInfoCache.Purge() +} + func NewSqlFileInfoStore(sqlStore *SqlStore) FileInfoStore { s := &SqlFileInfoStore{sqlStore} @@ -119,12 +132,39 @@ func (fs SqlFileInfoStore) GetByPath(path string) StoreChannel { return storeChannel } -func (fs SqlFileInfoStore) GetForPost(postId string) StoreChannel { +func (s SqlFileInfoStore) InvalidateFileInfosForPostCache(postId string) { + fileInfoCache.Remove(postId) +} + +func (fs SqlFileInfoStore) GetForPost(postId string, allowFromCache bool) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} + metrics := einterfaces.GetMetricsInterface() + + if allowFromCache { + if cacheItem, ok := fileInfoCache.Get(postId); ok { + if metrics != nil { + metrics.IncrementMemCacheHitCounter("File Info Cache") + } + + result.Data = cacheItem.([]*model.FileInfo) + storeChannel <- result + close(storeChannel) + return + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("File Info Cache") + } + } + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("File Info Cache") + } + } + var infos []*model.FileInfo if _, err := fs.GetReplica().Select(&infos, @@ -140,6 +180,7 @@ func (fs SqlFileInfoStore) GetForPost(postId string) StoreChannel { result.Err = model.NewLocAppError("SqlFileInfoStore.GetForPost", "store.sql_file_info.get_for_post.app_error", nil, "post_id="+postId+", "+err.Error()) } else { + fileInfoCache.AddWithExpiresInSecs(postId, infos, FILE_INFO_CACHE_SEC) result.Data = infos } diff --git a/store/sql_file_info_store_test.go b/store/sql_file_info_store_test.go index edb9dbd54..672e15ef2 100644 --- a/store/sql_file_info_store_test.go +++ b/store/sql_file_info_store_test.go @@ -114,7 +114,13 @@ func TestFileInfoGetForPost(t *testing.T) { infos[i] = Must(store.FileInfo().Save(info)).(*model.FileInfo) } - if result := <-store.FileInfo().GetForPost(postId); result.Err != nil { + if result := <-store.FileInfo().GetForPost(postId, false); result.Err != nil { + t.Fatal(result.Err) + } else if returned := result.Data.([]*model.FileInfo); len(returned) != 2 { + t.Fatal("should've returned exactly 2 file infos") + } + + if result := <-store.FileInfo().GetForPost(postId, true); result.Err != nil { t.Fatal(result.Err) } else if returned := result.Data.([]*model.FileInfo); len(returned) != 2 { t.Fatal("should've returned exactly 2 file infos") @@ -157,7 +163,7 @@ func TestFileInfoAttachToPost(t *testing.T) { info2 = Must(store.FileInfo().Get(info2.Id)).(*model.FileInfo) } - if result := <-store.FileInfo().GetForPost(postId); result.Err != nil { + if result := <-store.FileInfo().GetForPost(postId, false); result.Err != nil { t.Fatal(result.Err) } else if infos := result.Data.([]*model.FileInfo); len(infos) != 2 { t.Fatal("should've returned exactly 2 file infos") @@ -202,7 +208,7 @@ func TestFileInfoDeleteForPost(t *testing.T) { t.Fatal(result.Err) } - if infos := Must(store.FileInfo().GetForPost(postId)).([]*model.FileInfo); len(infos) != 0 { + if infos := Must(store.FileInfo().GetForPost(postId, false)).([]*model.FileInfo); len(infos) != 0 { t.Fatal("shouldn't have returned any file infos") } } diff --git a/store/store.go b/store/store.go index 96d9509b8..faf40c280 100644 --- a/store/store.go +++ b/store/store.go @@ -326,7 +326,8 @@ type FileInfoStore interface { Save(info *model.FileInfo) StoreChannel Get(id string) StoreChannel GetByPath(path string) StoreChannel - GetForPost(postId string) StoreChannel + GetForPost(postId string, allowFromCache bool) StoreChannel + InvalidateFileInfosForPostCache(postId string) AttachToPost(fileId string, postId string) StoreChannel DeleteForPost(postId string) StoreChannel } -- cgit v1.2.3-1-g7c22