Files
open-im-server/pkg/common/db/cache/conversation.go
T

212 lines
9.1 KiB
Go
Raw Normal View History

2023-02-02 16:11:24 +08:00
package cache
2023-02-02 19:40:54 +08:00
import (
"context"
2023-03-23 19:02:20 +08:00
"errors"
"math/big"
"strings"
"time"
2023-03-16 10:46:06 +08:00
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
2023-02-02 19:40:54 +08:00
"github.com/dtm-labs/rockscache"
"github.com/go-redis/redis/v8"
)
2023-02-09 10:55:21 +08:00
const (
2023-03-23 19:02:20 +08:00
conversationKey = "CONVERSATION:"
conversationIDsKey = "CONVERSATION_IDS:"
recvMsgOptKey = "RECV_MSG_OPT:"
superGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:"
superGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS_HASH:"
2023-02-20 10:10:02 +08:00
2023-03-23 19:02:20 +08:00
conversationExpireTime = time.Second * 60 * 60 * 12
)
2023-02-02 19:47:21 +08:00
2023-05-04 12:11:29 +08:00
// arg fn will exec when no data in msgCache
2023-02-02 19:47:21 +08:00
type ConversationCache interface {
2023-03-23 19:02:20 +08:00
metaCache
NewCache() ConversationCache
2023-05-04 12:11:29 +08:00
// get user's conversationIDs from msgCache
2023-03-23 19:02:20 +08:00
GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error)
DelConversationIDs(userIDs []string) ConversationCache
2023-05-04 12:11:29 +08:00
// get one conversation from msgCache
2023-03-23 19:02:20 +08:00
GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationTb.ConversationModel, error)
DelConvsersations(ownerUserID string, conversationIDs []string) ConversationCache
2023-04-21 14:51:57 +08:00
DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache
2023-05-04 12:11:29 +08:00
// get one conversation from msgCache
2023-03-23 19:02:20 +08:00
GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationTb.ConversationModel, error)
2023-05-04 12:11:29 +08:00
// get one user's all conversations from msgCache
2023-03-23 19:02:20 +08:00
GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*relationTb.ConversationModel, error)
2023-05-04 12:11:29 +08:00
// get user conversation recv msg from msgCache
2023-03-23 19:02:20 +08:00
GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error)
DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache
2023-02-09 10:55:21 +08:00
// get one super group recv msg but do not notification userID list
2023-03-23 19:02:20 +08:00
GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error)
2023-03-24 16:41:11 +08:00
DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache
2023-03-23 19:02:20 +08:00
// get one super group recv msg but do not notification userID list hash
GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error)
2023-03-24 16:41:11 +08:00
DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache
2023-02-02 19:47:21 +08:00
}
2023-02-09 10:55:21 +08:00
2023-03-23 19:02:20 +08:00
func NewConversationRedis(rdb redis.UniversalClient, opts rockscache.Options, db relationTb.ConversationModelInterface) ConversationCache {
rcClient := rockscache.NewClient(rdb, opts)
return &ConversationRedisCache{rcClient: rcClient, metaCache: NewMetaCacheRedis(rcClient), conversationDB: db, expireTime: conversationExpireTime}
2023-02-22 14:31:30 +08:00
}
2023-03-23 19:02:20 +08:00
type ConversationRedisCache struct {
metaCache
rcClient *rockscache.Client
conversationDB relationTb.ConversationModelInterface
expireTime time.Duration
2023-02-02 19:47:21 +08:00
}
2023-02-02 19:40:54 +08:00
2023-03-23 19:02:20 +08:00
func NewNewConversationRedis(rdb redis.UniversalClient, conversationDB *relation.ConversationGorm, options rockscache.Options) ConversationCache {
rcClient := rockscache.NewClient(rdb, options)
return &ConversationRedisCache{rcClient: rcClient, metaCache: NewMetaCacheRedis(rcClient), conversationDB: conversationDB, expireTime: conversationExpireTime}
2023-02-10 20:57:45 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) NewCache() ConversationCache {
2023-03-27 17:20:36 +08:00
return &ConversationRedisCache{rcClient: c.rcClient, metaCache: NewMetaCacheRedis(c.rcClient, c.metaCache.GetPreDelKeys()...), conversationDB: c.conversationDB, expireTime: c.expireTime}
2023-02-22 14:31:30 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) getConversationKey(ownerUserID, conversationID string) string {
return conversationKey + ownerUserID + ":" + conversationID
2023-02-22 14:31:30 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID string) string {
return conversationIDsKey + ownerUserID
2023-02-22 14:31:30 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
return superGroupRecvMsgNotNotifyUserIDsKey + groupID
2023-02-10 20:57:45 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) getRecvMsgOptKey(ownerUserID, conversationID string) string {
return recvMsgOptKey + ownerUserID + ":" + conversationID
2023-02-22 14:31:30 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string {
return superGroupRecvMsgNotNotifyUserIDsHashKey + groupID
2023-02-22 14:31:30 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) {
return getCache(ctx, c.rcClient, c.getConversationIDsKey(ownerUserID), c.expireTime, func(ctx context.Context) ([]string, error) {
return c.conversationDB.FindUserIDAllConversationID(ctx, ownerUserID)
})
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) DelConversationIDs(userIDs []string) ConversationCache {
var keys []string
for _, userID := range userIDs {
keys = append(keys, c.getConversationIDsKey(userID))
}
cache := c.NewCache()
cache.AddKeys(keys...)
return cache
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationTb.ConversationModel, error) {
return getCache(ctx, c.rcClient, c.getConversationKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (*relationTb.ConversationModel, error) {
return c.conversationDB.Take(ctx, ownerUserID, conversationID)
})
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) DelConvsersations(ownerUserID string, convsersationIDs []string) ConversationCache {
var keys []string
for _, conversationID := range convsersationIDs {
keys = append(keys, c.getConversationKey(ownerUserID, conversationID))
}
cache := c.NewCache()
cache.AddKeys(keys...)
return cache
}
func (c *ConversationRedisCache) GetConversationIndex(convsation *relationTb.ConversationModel, keys []string) (int, error) {
key := c.getConversationKey(convsation.OwnerUserID, convsation.ConversationID)
for _i, _key := range keys {
if _key == key {
return _i, nil
}
}
return 0, errors.New("not found key:" + key + " in keys")
}
func (c *ConversationRedisCache) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationTb.ConversationModel, error) {
var keys []string
for _, conversarionID := range conversationIDs {
keys = append(keys, c.getConversationKey(ownerUserID, conversarionID))
}
return batchGetCache(ctx, c.rcClient, keys, c.expireTime, c.GetConversationIndex, func(ctx context.Context) ([]*relationTb.ConversationModel, error) {
return c.conversationDB.Find(ctx, ownerUserID, conversationIDs)
})
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*relationTb.ConversationModel, error) {
conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID)
if err != nil {
return nil, err
}
var keys []string
for _, conversarionID := range conversationIDs {
keys = append(keys, c.getConversationKey(ownerUserID, conversarionID))
}
return batchGetCache(ctx, c.rcClient, keys, c.expireTime, c.GetConversationIndex, func(ctx context.Context) ([]*relationTb.ConversationModel, error) {
return c.conversationDB.FindUserIDAllConversations(ctx, ownerUserID)
})
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) {
return getCache(ctx, c.rcClient, c.getRecvMsgOptKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (opt int, err error) {
return c.conversationDB.GetUserRecvMsgOpt(ctx, ownerUserID, conversationID)
2023-02-20 10:10:02 +08:00
})
2023-02-03 16:10:51 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) {
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) {
return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
})
2023-02-02 19:40:54 +08:00
}
2023-04-21 14:51:57 +08:00
func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache {
2023-03-23 19:02:20 +08:00
var keys []string
for _, ownerUserID := range ownerUserIDs {
keys = append(keys, c.getConversationKey(ownerUserID, conversationID))
}
cache := c.NewCache()
cache.AddKeys(keys...)
return cache
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache {
cache := c.NewCache()
cache.AddKeys(c.getRecvMsgOptKey(ownerUserID, conversationID))
return cache
2023-02-02 19:40:54 +08:00
}
2023-03-24 16:41:11 +08:00
func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache {
2023-03-23 19:02:20 +08:00
cache := c.NewCache()
cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsKey(groupID))
return cache
2023-02-02 19:40:54 +08:00
}
2023-03-23 19:02:20 +08:00
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) {
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) {
userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
if err != nil {
return 0, err
}
utils.Sort(userIDs, true)
bi := big.NewInt(0)
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
return bi.Uint64(), nil
})
2023-02-02 19:40:54 +08:00
}
2023-03-24 16:41:11 +08:00
func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache {
cache := c.NewCache()
cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID))
return cache
2023-02-02 19:40:54 +08:00
}