From ffd6ccde2ed4b1d374d0835c5638a189df60a679 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Thu, 22 Dec 2016 18:14:54 -0500 Subject: Adding caching of last 60 posts. (#4880) --- store/sql_post_store.go | 34 +++++++++++++++++++++++++++++++++- store/sql_post_store_test.go | 28 +++++++++++++++++++++++++++- store/store.go | 2 +- 3 files changed, 61 insertions(+), 3 deletions(-) (limited to 'store') diff --git a/store/sql_post_store.go b/store/sql_post_store.go index 9c1faf4fc..c1aaee3e6 100644 --- a/store/sql_post_store.go +++ b/store/sql_post_store.go @@ -21,12 +21,17 @@ type SqlPostStore struct { const ( LAST_POST_TIME_CACHE_SIZE = 25000 LAST_POST_TIME_CACHE_SEC = 900 // 15 minutes + + LAST_POSTS_CACHE_SIZE = 1000 + LAST_POSTS_CACHE_SEC = 900 // 15 minutes ) var lastPostTimeCache = utils.NewLru(LAST_POST_TIME_CACHE_SIZE) +var lastPostsCache = utils.NewLru(LAST_POSTS_CACHE_SIZE) func ClearPostCaches() { lastPostTimeCache.Purge() + lastPostsCache.Purge() } func NewSqlPostStore(sqlStore *SqlStore) PostStore { @@ -224,6 +229,7 @@ type etagPosts struct { func (s SqlPostStore) InvalidateLastPostTimeCache(channelId string) { lastPostTimeCache.Remove(channelId) + lastPostsCache.Remove(channelId) } func (s SqlPostStore) GetEtag(channelId string, allowFromCache bool) StoreChannel { @@ -381,11 +387,12 @@ func (s SqlPostStore) PermanentDeleteByUser(userId string) StoreChannel { return storeChannel } -func (s SqlPostStore) GetPosts(channelId string, offset int, limit int) StoreChannel { +func (s SqlPostStore) GetPosts(channelId string, offset int, limit int, allowFromCache bool) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} + metrics := einterfaces.GetMetricsInterface() if limit > 1000 { result.Err = model.NewLocAppError("SqlPostStore.GetLinearPosts", "store.sql_post.get_posts.app_error", nil, "channelId="+channelId) @@ -394,6 +401,27 @@ func (s SqlPostStore) GetPosts(channelId string, offset int, limit int) StoreCha return } + if allowFromCache && offset == 0 && limit == 60 { + if cacheItem, ok := lastPostsCache.Get(channelId); ok { + if metrics != nil { + metrics.IncrementMemCacheHitCounter("Last Posts Cache") + } + + result.Data = cacheItem.(*model.PostList) + storeChannel <- result + close(storeChannel) + return + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("Last Posts Cache") + } + } + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("Last Posts Cache") + } + } + rpc := s.getRootPosts(channelId, offset, limit) cpc := s.getParentsPosts(channelId, offset, limit) @@ -418,6 +446,10 @@ func (s SqlPostStore) GetPosts(channelId string, offset int, limit int) StoreCha list.MakeNonNil() + if offset == 0 && limit == 60 { + lastPostsCache.AddWithExpiresInSecs(channelId, list, LAST_POSTS_CACHE_SEC) + } + result.Data = list } diff --git a/store/sql_post_store_test.go b/store/sql_post_store_test.go index 3299d67e1..eb22979db 100644 --- a/store/sql_post_store_test.go +++ b/store/sql_post_store_test.go @@ -491,7 +491,7 @@ func TestPostStoreGetPostsWtihDetails(t *testing.T) { o5.RootId = o4.Id o5 = (<-store.Post().Save(o5)).Data.(*model.Post) - r1 := (<-store.Post().GetPosts(o1.ChannelId, 0, 4)).Data.(*model.PostList) + r1 := (<-store.Post().GetPosts(o1.ChannelId, 0, 4, false)).Data.(*model.PostList) if r1.Order[0] != o5.Id { t.Fatal("invalid order") @@ -516,6 +516,32 @@ func TestPostStoreGetPostsWtihDetails(t *testing.T) { if r1.Posts[o1.Id].Message != o1.Message { t.Fatal("Missing parent") } + + r2 := (<-store.Post().GetPosts(o1.ChannelId, 0, 4, true)).Data.(*model.PostList) + + if r2.Order[0] != o5.Id { + t.Fatal("invalid order") + } + + if r2.Order[1] != o4.Id { + t.Fatal("invalid order") + } + + if r2.Order[2] != o3.Id { + t.Fatal("invalid order") + } + + if r2.Order[3] != o2a.Id { + t.Fatal("invalid order") + } + + if len(r2.Posts) != 6 { //the last 4, + o1 (o2a and o3's parent) + o2 (in same thread as o2a and o3) + t.Fatal("wrong size") + } + + if r2.Posts[o1.Id].Message != o1.Message { + t.Fatal("Missing parent") + } } func TestPostStoreGetPostsBeforeAfter(t *testing.T) { diff --git a/store/store.go b/store/store.go index 643fe925a..8521713d5 100644 --- a/store/store.go +++ b/store/store.go @@ -127,7 +127,7 @@ type PostStore interface { Get(id string) StoreChannel Delete(postId string, time int64) StoreChannel PermanentDeleteByUser(userId string) StoreChannel - GetPosts(channelId string, offset int, limit int) StoreChannel + GetPosts(channelId string, offset int, limit int, allowFromCache bool) StoreChannel GetFlaggedPosts(userId string, offset int, limit int) StoreChannel GetPostsBefore(channelId string, postId string, numPosts int, offset int) StoreChannel GetPostsAfter(channelId string, postId string, numPosts int, offset int) StoreChannel -- cgit v1.2.3-1-g7c22