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

370 lines
14 KiB
Go
Raw Normal View History

2023-01-17 14:40:20 +08:00
package cache
import (
"context"
2023-03-23 19:02:20 +08:00
"math/big"
"strings"
"time"
2023-03-16 10:46:06 +08:00
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
2023-03-23 19:02:20 +08:00
unrelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
2023-03-16 10:46:06 +08:00
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
2023-01-17 14:40:20 +08:00
"github.com/dtm-labs/rockscache"
"github.com/go-redis/redis/v8"
)
2023-01-31 18:55:22 +08:00
const (
2023-03-27 15:05:40 +08:00
groupExpireTime = time.Second * 60 * 60 * 12
groupInfoKey = "GROUP_INFO:"
groupMemberIDsKey = "GROUP_MEMBER_IDS:"
groupMembersHashKey = "GROUP_MEMBERS_HASH:"
groupMemberInfoKey = "GROUP_MEMBER_INFO:"
joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:"
SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:"
joinedGroupsKey = "JOIN_GROUPS_KEY:"
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
2023-01-31 18:55:22 +08:00
)
2023-01-17 14:40:20 +08:00
2023-02-09 10:55:21 +08:00
type GroupCache interface {
2023-03-23 19:02:20 +08:00
metaCache
NewCache() GroupCache
2023-02-20 17:43:09 +08:00
GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationTb.GroupModel, err error)
GetGroupInfo(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error)
2023-03-27 15:05:40 +08:00
DelGroupsInfo(groupIDs ...string) GroupCache
2023-02-20 17:43:09 +08:00
GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error)
2023-03-23 19:02:20 +08:00
DelJoinedSuperGroupIDs(userIDs ...string) GroupCache
2023-03-27 15:05:40 +08:00
GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationTb.SuperGroupModel, err error)
DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
2023-03-23 19:02:20 +08:00
GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error)
GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationTb.GroupSimpleUserID, error)
DelGroupMembersHash(groupID string) GroupCache
2023-02-20 17:43:09 +08:00
GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error)
2023-03-23 19:02:20 +08:00
GetGroupsMemberIDs(ctx context.Context, groupIDs []string) (groupMemberIDs map[string][]string, err error)
DelGroupMemberIDs(groupID string) GroupCache
2023-03-29 14:30:38 +08:00
GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error)
2023-03-23 19:02:20 +08:00
DelJoinedGroupID(userID ...string) GroupCache
2023-02-20 17:43:09 +08:00
GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationTb.GroupMemberModel, err error)
2023-03-29 14:30:38 +08:00
GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationTb.GroupMemberModel, err error)
2023-03-28 19:24:59 +08:00
GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationTb.GroupMemberModel, err error)
2023-03-29 17:59:52 +08:00
GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationTb.GroupMemberModel, err error)
2023-03-29 10:19:20 +08:00
2023-03-23 19:02:20 +08:00
DelGroupMembersInfo(groupID string, userID ...string) GroupCache
GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error)
DelGroupsMemberNum(groupID ...string) GroupCache
2023-02-20 17:43:09 +08:00
}
2023-02-09 10:55:21 +08:00
type GroupCacheRedis struct {
2023-03-23 19:02:20 +08:00
metaCache
groupDB relationTb.GroupModelInterface
groupMemberDB relationTb.GroupMemberModelInterface
groupRequestDB relationTb.GroupRequestModelInterface
mongoDB unrelationTb.SuperGroupModelInterface
expireTime time.Duration
rcClient *rockscache.Client
}
func NewGroupCacheRedis(rdb redis.UniversalClient, groupDB relationTb.GroupModelInterface, groupMemberDB relationTb.GroupMemberModelInterface, groupRequestDB relationTb.GroupRequestModelInterface, mongoClient unrelationTb.SuperGroupModelInterface, opts rockscache.Options) GroupCache {
rcClient := rockscache.NewClient(rdb, opts)
return &GroupCacheRedis{rcClient: rcClient, expireTime: groupExpireTime,
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient),
2023-01-31 18:55:22 +08:00
}
2023-01-17 16:36:34 +08:00
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) NewCache() GroupCache {
2023-03-27 17:20:36 +08:00
return &GroupCacheRedis{rcClient: g.rcClient, expireTime: g.expireTime, groupDB: g.groupDB, groupMemberDB: g.groupMemberDB, groupRequestDB: g.groupRequestDB, mongoDB: g.mongoDB, metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...)}
2023-03-23 19:02:20 +08:00
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string {
2023-01-31 18:55:22 +08:00
return groupInfoKey + groupID
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getJoinedSuperGroupsIDKey(userID string) string {
2023-01-31 18:55:22 +08:00
return joinedSuperGroupsKey + userID
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string {
2023-01-31 18:55:22 +08:00
return joinedGroupsKey + userID
}
2023-03-27 15:05:40 +08:00
func (g *GroupCacheRedis) getSuperGroupMemberIDsKey(groupID string) string {
return SuperGroupMemberIDsKey + groupID
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string {
2023-01-31 18:55:22 +08:00
return groupMembersHashKey + groupID
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getGroupMemberIDsKey(groupID string) string {
2023-01-31 18:55:22 +08:00
return groupMemberIDsKey + groupID
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getGroupMemberInfoKey(groupID, userID string) string {
2023-01-31 18:55:22 +08:00
return groupMemberInfoKey + groupID + "-" + userID
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string {
2023-01-31 18:55:22 +08:00
return groupMemberNumKey + groupID
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) GetGroupIndex(group *relationTb.GroupModel, keys []string) (int, error) {
key := g.getGroupInfoKey(group.GroupID)
for i, _key := range keys {
if _key == key {
return i, nil
}
}
return 0, errIndex
}
func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationTb.GroupMemberModel, keys []string) (int, error) {
key := g.getGroupMemberInfoKey(groupMember.GroupID, groupMember.UserID)
for i, _key := range keys {
if _key == key {
return i, nil
}
}
return 0, errIndex
}
2023-02-01 17:07:56 +08:00
// / groupInfo
2023-02-09 19:40:45 +08:00
func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationTb.GroupModel, err error) {
2023-03-23 19:02:20 +08:00
var keys []string
for _, group := range groupIDs {
keys = append(keys, g.getGroupInfoKey(group))
}
return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupIndex, func(ctx context.Context) ([]*relationTb.GroupModel, error) {
return g.groupDB.Find(ctx, groupIDs)
2023-02-09 19:40:45 +08:00
})
2023-01-17 14:40:20 +08:00
}
2023-02-09 17:54:31 +08:00
func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error) {
2023-03-23 19:02:20 +08:00
return getCache(ctx, g.rcClient, g.getGroupInfoKey(groupID), g.expireTime, func(ctx context.Context) (*relationTb.GroupModel, error) {
return g.groupDB.Take(ctx, groupID)
2023-02-09 19:40:45 +08:00
})
2023-01-17 14:40:20 +08:00
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache {
new := g.NewCache()
var keys []string
for _, groupID := range groupIDs {
keys = append(keys, g.getGroupInfoKey(groupID))
2023-01-29 10:31:01 +08:00
}
2023-03-23 19:02:20 +08:00
new.AddKeys(keys...)
return new
2023-01-31 18:55:22 +08:00
}
2023-03-27 15:05:40 +08:00
func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) {
return getCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID)
if err != nil {
return nil, err
}
return userGroup.GroupIDs, nil
})
}
func (g *GroupCacheRedis) GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationTb.SuperGroupModel, err error) {
var keys []string
for _, group := range groupIDs {
keys = append(keys, g.getSuperGroupMemberIDsKey(group))
}
return batchGetCache(ctx, g.rcClient, keys, g.expireTime, func(model *unrelationTb.SuperGroupModel, keys []string) (int, error) {
for i, key := range keys {
if g.getSuperGroupMemberIDsKey(model.GroupID) == key {
return i, nil
}
}
return 0, errIndex
}, func(ctx context.Context) ([]*unrelationTb.SuperGroupModel, error) {
return g.mongoDB.FindSuperGroup(ctx, groupIDs)
})
}
2023-03-23 19:02:20 +08:00
// userJoinSuperGroup
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache {
new := g.NewCache()
var keys []string
for _, userID := range userIDs {
keys = append(keys, g.getJoinedSuperGroupsIDKey(userID))
}
new.AddKeys(keys...)
return new
2023-01-31 18:55:22 +08:00
}
2023-03-27 15:05:40 +08:00
func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache {
new := g.NewCache()
var keys []string
for _, groupID := range groupIDs {
keys = append(keys, g.getSuperGroupMemberIDsKey(groupID))
}
new.AddKeys(keys...)
return new
2023-01-31 18:55:22 +08:00
}
// groupMembersHash
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
2023-02-10 15:36:25 +08:00
userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
2023-01-31 18:55:22 +08:00
if err != nil {
2023-02-10 15:36:25 +08:00
return 0, err
2023-01-31 18:55:22 +08:00
}
2023-02-10 15:36:25 +08:00
utils.Sort(userIDs, true)
2023-01-31 18:55:22 +08:00
bi := big.NewInt(0)
2023-02-10 15:36:25 +08:00
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
return bi.Uint64(), nil
})
2023-01-31 18:55:22 +08:00
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationTb.GroupSimpleUserID, error) {
2023-02-10 19:17:33 +08:00
res := make(map[string]*relationTb.GroupSimpleUserID)
for _, groupID := range groupIDs {
2023-03-23 19:02:20 +08:00
userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return nil, err
}
2023-02-10 19:17:33 +08:00
users := &relationTb.GroupSimpleUserID{}
if len(userIDs) > 0 {
utils.Sort(userIDs, true)
bi := big.NewInt(0)
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
users.Hash = bi.Uint64()
2023-03-23 19:02:20 +08:00
users.MemberNum = uint32(len(userIDs))
2023-02-10 19:17:33 +08:00
}
res[groupID] = users
}
return res, nil
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache {
cache := g.NewCache()
cache.AddKeys(g.getGroupMembersHashKey(groupID))
return cache
2023-01-31 18:55:22 +08:00
}
// groupMemberIDs
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
2023-03-23 19:02:20 +08:00
return getCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) {
return g.groupMemberDB.FindMemberUserID(ctx, groupID)
2023-02-10 15:36:25 +08:00
})
2023-01-29 10:31:01 +08:00
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) GetGroupsMemberIDs(ctx context.Context, groupIDs []string) (map[string][]string, error) {
m := make(map[string][]string)
for _, groupID := range groupIDs {
userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return nil, err
}
m[groupID] = userIDs
}
return m, nil
}
func (g *GroupCacheRedis) DelGroupMemberIDs(groupID string) GroupCache {
cache := g.NewCache()
cache.AddKeys(g.getGroupMemberIDsKey(groupID))
return cache
}
func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) {
return getCache(ctx, g.rcClient, g.getJoinedGroupsKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
return g.groupMemberDB.FindUserJoinedGroupID(ctx, userID)
})
}
func (g *GroupCacheRedis) DelJoinedGroupID(userIDs ...string) GroupCache {
var keys []string
for _, userID := range userIDs {
keys = append(keys, g.getJoinedGroupsKey(userID))
}
cache := g.NewCache()
cache.AddKeys(keys...)
return cache
}
2023-02-10 19:17:33 +08:00
func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationTb.GroupMemberModel, err error) {
2023-03-23 19:02:20 +08:00
return getCache(ctx, g.rcClient, g.getGroupMemberInfoKey(groupID, userID), g.expireTime, func(ctx context.Context) (*relationTb.GroupMemberModel, error) {
return g.groupMemberDB.Take(ctx, groupID, userID)
2023-02-10 19:17:33 +08:00
})
2023-02-09 17:54:31 +08:00
}
2023-03-29 14:30:38 +08:00
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*relationTb.GroupMemberModel, error) {
2023-03-23 19:02:20 +08:00
var keys []string
for _, userID := range userIDs {
keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
}
return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationTb.GroupMemberModel, error) {
2023-03-29 14:30:38 +08:00
return g.groupMemberDB.Find(ctx, []string{groupID}, userIDs, nil)
2023-03-23 19:02:20 +08:00
})
}
2023-03-29 17:59:52 +08:00
func (g *GroupCacheRedis) GetGroupMembersPage(ctx context.Context, groupID string, userIDs []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationTb.GroupMemberModel, err error) {
2023-03-29 10:19:20 +08:00
groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil {
2023-03-29 17:59:52 +08:00
return 0, nil, err
2023-03-29 10:19:20 +08:00
}
2023-03-29 14:44:44 +08:00
if userIDs != nil {
userIDs = utils.BothExist(userIDs, groupMemberIDs)
} else {
userIDs = groupMemberIDs
}
2023-03-29 17:59:52 +08:00
groupMembers, err = g.GetGroupMembersInfo(ctx, groupID, utils.Paginate(userIDs, int(showNumber), int(showNumber)))
return uint32(len(userIDs)), groupMembers, err
2023-03-29 10:19:20 +08:00
}
2023-03-28 19:24:59 +08:00
func (g *GroupCacheRedis) GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationTb.GroupMemberModel, err error) {
groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return nil, err
}
2023-03-29 14:30:38 +08:00
return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs)
2023-03-28 19:24:59 +08:00
}
2023-03-23 19:02:20 +08:00
func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID string) ([]*relationTb.GroupMemberModel, error) {
groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return nil, err
}
var keys []string
for _, groupMemberID := range groupMemberIDs {
keys = append(keys, g.getGroupMemberInfoKey(groupID, groupMemberID))
}
return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationTb.GroupMemberModel, error) {
return g.groupMemberDB.Find(ctx, []string{groupID}, groupMemberIDs, nil)
})
}
func (g *GroupCacheRedis) DelGroupMembersInfo(groupID string, userIDs ...string) GroupCache {
var keys []string
for _, userID := range userIDs {
keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
}
cache := g.NewCache()
cache.AddKeys(keys...)
return cache
}
func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error) {
return getCache(ctx, g.rcClient, g.getGroupMemberNumKey(groupID), g.expireTime, func(ctx context.Context) (int64, error) {
return g.groupMemberDB.TakeGroupMemberNum(ctx, groupID)
})
}
func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache {
var keys []string
for _, groupID := range groupID {
keys = append(keys, g.getGroupMemberNumKey(groupID))
2023-02-10 15:36:25 +08:00
}
2023-03-23 19:02:20 +08:00
cache := g.NewCache()
cache.AddKeys(keys...)
return cache
2023-02-10 15:36:25 +08:00
}