diff options
-rw-r--r-- | api/emoji.go | 5 | ||||
-rw-r--r-- | store/sql_emoji_store.go | 36 | ||||
-rw-r--r-- | store/sql_emoji_store_test.go | 8 | ||||
-rw-r--r-- | store/store.go | 2 |
4 files changed, 46 insertions, 5 deletions
diff --git a/api/emoji.go b/api/emoji.go index 8f665fbc1..2f94fb0e0 100644 --- a/api/emoji.go +++ b/api/emoji.go @@ -211,7 +211,7 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) { } var emoji *model.Emoji - if result := <-app.Srv.Store.Emoji().Get(id); result.Err != nil { + if result := <-app.Srv.Store.Emoji().Get(id, false); result.Err != nil { c.Err = result.Err return } else { @@ -269,7 +269,7 @@ func getEmojiImage(c *Context, w http.ResponseWriter, r *http.Request) { return } - if result := <-app.Srv.Store.Emoji().Get(id); result.Err != nil { + if result := <-app.Srv.Store.Emoji().Get(id, true); result.Err != nil { c.Err = result.Err return } else { @@ -288,6 +288,7 @@ func getEmojiImage(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "image/"+imageType) } + w.Header().Set("Cache-Control", "max-age=2592000, public") w.Write(img) } } diff --git a/store/sql_emoji_store.go b/store/sql_emoji_store.go index f9218d8d7..5aad725f9 100644 --- a/store/sql_emoji_store.go +++ b/store/sql_emoji_store.go @@ -4,9 +4,18 @@ package store import ( + "github.com/mattermost/platform/einterfaces" "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" ) +const ( + EMOJI_CACHE_SIZE = 5000 + EMOJI_CACHE_SEC = 1800 // 60 mins +) + +var emojiCache *utils.Cache = utils.NewLru(EMOJI_CACHE_SIZE) + type SqlEmojiStore struct { *SqlStore } @@ -58,11 +67,32 @@ func (es SqlEmojiStore) Save(emoji *model.Emoji) StoreChannel { return storeChannel } -func (es SqlEmojiStore) Get(id string) StoreChannel { +func (es SqlEmojiStore) Get(id string, allowFromCache bool) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} + metrics := einterfaces.GetMetricsInterface() + + if allowFromCache { + if cacheItem, ok := emojiCache.Get(id); ok { + if metrics != nil { + metrics.IncrementMemCacheHitCounter("Emoji") + } + result.Data = cacheItem.(map[string]*model.Emoji) + storeChannel <- result + close(storeChannel) + return + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("Emoji") + } + } + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("Emoji") + } + } var emoji *model.Emoji @@ -77,6 +107,10 @@ func (es SqlEmojiStore) Get(id string) StoreChannel { result.Err = model.NewLocAppError("SqlEmojiStore.Get", "store.sql_emoji.get.app_error", nil, "id="+id+", "+err.Error()) } else { result.Data = emoji + + if allowFromCache { + emojiCache.AddWithExpiresInSecs(id, emoji, EMOJI_CACHE_SEC) + } } storeChannel <- result diff --git a/store/sql_emoji_store_test.go b/store/sql_emoji_store_test.go index f9c42c906..3c05257f5 100644 --- a/store/sql_emoji_store_test.go +++ b/store/sql_emoji_store_test.go @@ -74,7 +74,13 @@ func TestEmojiGet(t *testing.T) { }() for _, emoji := range emojis { - if result := <-store.Emoji().Get(emoji.Id); result.Err != nil { + if result := <-store.Emoji().Get(emoji.Id, false); result.Err != nil { + t.Fatalf("failed to get emoji with id %v: %v", emoji.Id, result.Err) + } + } + + for _, emoji := range emojis { + if result := <-store.Emoji().Get(emoji.Id, true); result.Err != nil { t.Fatalf("failed to get emoji with id %v: %v", emoji.Id, result.Err) } } diff --git a/store/store.go b/store/store.go index c94dbc469..00866d523 100644 --- a/store/store.go +++ b/store/store.go @@ -304,7 +304,7 @@ type PasswordRecoveryStore interface { type EmojiStore interface { Save(emoji *model.Emoji) StoreChannel - Get(id string) StoreChannel + Get(id string, allowFromCache bool) StoreChannel GetByName(name string) StoreChannel GetAll() StoreChannel Delete(id string, time int64) StoreChannel |