diff options
Diffstat (limited to 'store')
-rw-r--r-- | store/sql_channel_store.go | 41 | ||||
-rw-r--r-- | store/sql_channel_store_test.go | 28 | ||||
-rw-r--r-- | store/store.go | 3 |
3 files changed, 56 insertions, 16 deletions
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go index 47c172f77..7cdebba8a 100644 --- a/store/sql_channel_store.go +++ b/store/sql_channel_store.go @@ -26,6 +26,9 @@ const ( CHANNEL_MEMBERS_COUNTS_CACHE_SIZE = 20000 CHANNEL_MEMBERS_COUNTS_CACHE_SEC = 900 // 15 mins + + CHANNEL_CACHE_SIZE = 5000 + CHANNEL_CACHE_SEC = 900 // 15 mins ) type SqlChannelStore struct { @@ -34,10 +37,12 @@ type SqlChannelStore struct { var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE) var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE) +var channelCache = utils.NewLru(CHANNEL_CACHE_SIZE) func ClearChannelCaches() { channelMemberCountsCache.Purge() allChannelMembersForUserCache.Purge() + channelCache.Purge() } func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore { @@ -297,19 +302,24 @@ func (s SqlChannelStore) extraUpdated(channel *model.Channel) StoreChannel { return storeChannel } -func (s SqlChannelStore) Get(id string) StoreChannel { - return s.get(id, false) +func (us SqlChannelStore) InvalidateChannel(id string) { + channelCache.Remove(id) +} + +func (s SqlChannelStore) Get(id string, allowFromCache bool) StoreChannel { + return s.get(id, false, allowFromCache) } func (s SqlChannelStore) GetFromMaster(id string) StoreChannel { - return s.get(id, true) + return s.get(id, true, false) } -func (s SqlChannelStore) get(id string, master bool) StoreChannel { +func (s SqlChannelStore) get(id string, master bool, allowFromCache bool) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} + metrics := einterfaces.GetMetricsInterface() var db *gorp.DbMap if master { @@ -318,12 +328,33 @@ func (s SqlChannelStore) get(id string, master bool) StoreChannel { db = s.GetReplica() } + if allowFromCache { + if cacheItem, ok := channelCache.Get(id); ok { + if metrics != nil { + metrics.IncrementMemCacheHitCounter("Channel") + } + result.Data = cacheItem.(*model.Channel) + storeChannel <- result + close(storeChannel) + return + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("Channel") + } + } + } else { + if metrics != nil { + metrics.IncrementMemCacheMissCounter("Channel") + } + } + if obj, err := db.Get(model.Channel{}, id); err != nil { result.Err = model.NewLocAppError("SqlChannelStore.Get", "store.sql_channel.get.find.app_error", nil, "id="+id+", "+err.Error()) } else if obj == nil { result.Err = model.NewLocAppError("SqlChannelStore.Get", "store.sql_channel.get.existing.app_error", nil, "id="+id) } else { result.Data = obj.(*model.Channel) + channelCache.AddWithExpiresInSecs(id, obj.(*model.Channel), CHANNEL_MEMBERS_COUNTS_CACHE_SEC) } storeChannel <- result @@ -869,7 +900,7 @@ func (s SqlChannelStore) RemoveMember(channelId string, userId string) StoreChan result := StoreResult{} // Grab the channel we are saving this member to - if cr := <-s.Get(channelId); cr.Err != nil { + if cr := <-s.Get(channelId, true); cr.Err != nil { result.Err = cr.Err } else { channel := cr.Data.(*model.Channel) diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go index 64e44cbb3..7aeef98cc 100644 --- a/store/sql_channel_store_test.go +++ b/store/sql_channel_store_test.go @@ -181,7 +181,7 @@ func TestChannelStoreGet(t *testing.T) { o1.Type = model.CHANNEL_OPEN Must(store.Channel().Save(&o1)) - if r1 := <-store.Channel().Get(o1.Id); r1.Err != nil { + if r1 := <-store.Channel().Get(o1.Id, false); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(*model.Channel).ToJson() != o1.ToJson() { @@ -189,7 +189,7 @@ func TestChannelStoreGet(t *testing.T) { } } - if err := (<-store.Channel().Get("")).Err; err == nil { + if err := (<-store.Channel().Get("", false)).Err; err == nil { t.Fatal("Missing id should have failed") } @@ -223,7 +223,7 @@ func TestChannelStoreGet(t *testing.T) { Must(store.Channel().SaveDirectChannel(&o2, &m1, &m2)) - if r2 := <-store.Channel().Get(o2.Id); r2.Err != nil { + if r2 := <-store.Channel().Get(o2.Id, false); r2.Err != nil { t.Fatal(r2.Err) } else { if r2.Data.(*model.Channel).ToJson() != o2.ToJson() { @@ -231,6 +231,14 @@ func TestChannelStoreGet(t *testing.T) { } } + if r4 := <-store.Channel().Get(o2.Id, true); r4.Err != nil { + t.Fatal(r4.Err) + } else { + if r4.Data.(*model.Channel).ToJson() != o2.ToJson() { + t.Fatal("invalid returned channel") + } + } + if r3 := <-store.Channel().GetAll(o1.TeamId); r3.Err != nil { t.Fatal(r3.Err) } else { @@ -311,7 +319,7 @@ func TestChannelStoreDelete(t *testing.T) { t.Fatal(r.Err) } - if r := <-store.Channel().Get(o1.Id); r.Data.(*model.Channel).DeleteAt == 0 { + if r := <-store.Channel().Get(o1.Id, false); r.Data.(*model.Channel).DeleteAt == 0 { t.Fatal("should have been deleted") } @@ -367,7 +375,7 @@ func TestChannelMemberStore(t *testing.T) { c1.Type = model.CHANNEL_OPEN c1 = *Must(store.Channel().Save(&c1)).(*model.Channel) - c1t1 := (<-store.Channel().Get(c1.Id)).Data.(*model.Channel) + c1t1 := (<-store.Channel().Get(c1.Id, false)).Data.(*model.Channel) t1 := c1t1.ExtraUpdateAt u1 := model.User{} @@ -394,7 +402,7 @@ func TestChannelMemberStore(t *testing.T) { o2.NotifyProps = model.GetDefaultChannelNotifyProps() Must(store.Channel().SaveMember(&o2)) - c1t2 := (<-store.Channel().Get(c1.Id)).Data.(*model.Channel) + c1t2 := (<-store.Channel().Get(c1.Id, false)).Data.(*model.Channel) t2 := c1t2.ExtraUpdateAt if t2 <= t1 { @@ -423,7 +431,7 @@ func TestChannelMemberStore(t *testing.T) { t.Fatal("should have removed 1 member") } - c1t3 := (<-store.Channel().Get(c1.Id)).Data.(*model.Channel) + c1t3 := (<-store.Channel().Get(c1.Id, false)).Data.(*model.Channel) t3 := c1t3.ExtraUpdateAt if t3 <= t2 || t3 <= t1 { @@ -439,7 +447,7 @@ func TestChannelMemberStore(t *testing.T) { t.Fatal("Should have been a duplicate") } - c1t4 := (<-store.Channel().Get(c1.Id)).Data.(*model.Channel) + c1t4 := (<-store.Channel().Get(c1.Id, false)).Data.(*model.Channel) t4 := c1t4.ExtraUpdateAt if t4 != t3 { t.Fatal("Should not update time upon failure") @@ -456,7 +464,7 @@ func TestChannelDeleteMemberStore(t *testing.T) { c1.Type = model.CHANNEL_OPEN c1 = *Must(store.Channel().Save(&c1)).(*model.Channel) - c1t1 := (<-store.Channel().Get(c1.Id)).Data.(*model.Channel) + c1t1 := (<-store.Channel().Get(c1.Id, false)).Data.(*model.Channel) t1 := c1t1.ExtraUpdateAt u1 := model.User{} @@ -483,7 +491,7 @@ func TestChannelDeleteMemberStore(t *testing.T) { o2.NotifyProps = model.GetDefaultChannelNotifyProps() Must(store.Channel().SaveMember(&o2)) - c1t2 := (<-store.Channel().Get(c1.Id)).Data.(*model.Channel) + c1t2 := (<-store.Channel().Get(c1.Id, false)).Data.(*model.Channel) t2 := c1t2.ExtraUpdateAt if t2 <= t1 { diff --git a/store/store.go b/store/store.go index 2f5065b88..9fe566844 100644 --- a/store/store.go +++ b/store/store.go @@ -85,7 +85,8 @@ type ChannelStore interface { CreateDirectChannel(userId string, otherUserId string) StoreChannel SaveDirectChannel(channel *model.Channel, member1 *model.ChannelMember, member2 *model.ChannelMember) StoreChannel Update(channel *model.Channel) StoreChannel - Get(id string) StoreChannel + Get(id string, allowFromCache bool) StoreChannel + InvalidateChannel(id string) GetFromMaster(id string) StoreChannel Delete(channelId string, time int64) StoreChannel SetDeleteAt(channelId string, deleteAt int64, updateAt int64) StoreChannel |