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

335 lines
12 KiB
Go
Raw Normal View History

2023-01-17 14:40:20 +08:00
package cache
import (
2023-01-28 13:19:36 +08:00
"Open_IM/pkg/common/db/relation"
2023-02-09 10:55:21 +08:00
relationTb "Open_IM/pkg/common/db/table/relation"
2023-01-31 18:55:22 +08:00
"Open_IM/pkg/common/db/unrelation"
2023-01-30 11:14:18 +08:00
"Open_IM/pkg/common/tracelog"
2023-01-17 14:40:20 +08:00
"Open_IM/pkg/utils"
"context"
"encoding/json"
"github.com/dtm-labs/rockscache"
"github.com/go-redis/redis/v8"
2023-01-31 18:55:22 +08:00
"math/big"
"strconv"
2023-02-10 15:36:25 +08:00
"strings"
2023-01-17 14:40:20 +08:00
"time"
)
2023-01-31 18:55:22 +08:00
const (
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:"
joinedGroupsKey = "JOIN_GROUPS_KEY:"
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
)
2023-01-17 14:40:20 +08:00
2023-02-09 10:55:21 +08:00
type GroupCache interface {
GetGroupsInfo(ctx context.Context, groupIDs []string, fn func(ctx context.Context, groupIDs []string) (groups []*relationTb.GroupModel, err error)) (groups []*relationTb.GroupModel, err error)
DelGroupsInfo(ctx context.Context, groupID string) (err error)
GetGroupInfo(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error)) (group *relationTb.GroupModel, err error)
DelGroupInfo(ctx context.Context, groupID string) (err error)
2023-02-09 16:11:18 +08:00
BatchDelJoinedSuperGroupIDs(ctx context.Context, userIDs []string, fn func(ctx context.Context, userIDs []string) error) (err error)
GetJoinedSuperGroupIDs(ctx context.Context, userID string, fn func(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error)) (joinedSuperGroupIDs []string, err error)
2023-02-09 17:54:31 +08:00
DelJoinedSuperGroupIDs(ctx context.Context, userID string) (err error)
2023-02-09 16:11:18 +08:00
GetGroupMembersHash(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (hashCodeUint64 uint64, err error)) (hashCodeUint64 uint64, err error)
DelGroupMembersHash(ctx context.Context, groupID string) (err error)
GetGroupMemberIDs(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (groupMemberIDs []string, err error)) (groupMemberIDs []string, err error)
2023-02-09 17:54:31 +08:00
DelGroupMemberIDs(ctx context.Context, groupID string) error
2023-02-09 16:11:18 +08:00
GetJoinedGroupIDs(ctx context.Context, userID string, fn func(ctx context.Context, userID string) (joinedGroupIDs []string, err error)) (joinedGroupIDs []string, err error)
DelJoinedGroupIDs(ctx context.Context, userID string) (err error)
GetGroupMemberInfo(ctx context.Context, groupID, userID string, fn func(ctx context.Context, groupID, userID string) (groupMember *relationTb.GroupMemberModel, err error)) (groupMember *relationTb.GroupMemberModel, err error)
DelGroupMemberInfo(ctx context.Context, groupID, userID string) (err error)
GetGroupMemberNum(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (num int, err error)) (num int, err error)
DelGroupMemberNum(ctx context.Context, groupID string) (err error)
2023-02-09 10:55:21 +08:00
}
type GroupCacheRedis struct {
2023-02-09 19:40:45 +08:00
group relationTb.GroupModelInterface
groupMember relationTb.GroupMemberModelInterface
groupRequest relationTb.GroupRequestModelInterface
2023-02-02 16:11:24 +08:00
mongoDB *unrelation.SuperGroupMongoDriver
2023-01-29 10:31:01 +08:00
expireTime time.Duration
redisClient *RedisClient
rcClient *rockscache.Client
2023-01-31 18:55:22 +08:00
}
2023-02-09 19:40:45 +08:00
func NewGroupCacheRedis(rdb redis.UniversalClient, groupDB relationTb.GroupModelInterface, groupMemberDB relationTb.GroupMemberModelInterface, groupRequestDB relationTb.GroupRequestModelInterface, mongoClient *unrelation.SuperGroupMongoDriver, opts rockscache.Options) *GroupCacheRedis {
2023-02-09 10:55:21 +08:00
return &GroupCacheRedis{rcClient: rockscache.NewClient(rdb, opts), expireTime: groupExpireTime,
2023-01-31 18:55:22 +08:00
group: groupDB, groupMember: groupMemberDB, groupRequest: groupRequestDB, redisClient: NewRedisClient(rdb),
2023-02-02 19:43:51 +08:00
mongoDB: mongoClient,
2023-01-31 18:55:22 +08:00
}
2023-01-17 16:36:34 +08:00
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) getRedisClient() *RedisClient {
2023-01-17 16:36:34 +08:00
return g.redisClient
2023-01-17 14:40: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-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-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-02-10 10:48:49 +08:00
return GetCacheFor(ctx, groupIDs, func(ctx context.Context, groupID string) (*relationTb.GroupModel, error) {
2023-02-09 19:40:45 +08:00
return g.GetGroupInfo(ctx, groupID)
})
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-02-09 19:40:45 +08:00
return GetCache(ctx, g.rcClient, g.getGroupInfoKey(groupID), g.expireTime, func(ctx context.Context) (*relationTb.GroupModel, error) {
return g.group.Take(ctx, groupID)
})
2023-01-17 14:40:20 +08:00
}
2023-01-31 18:55:22 +08:00
// userJoinSuperGroup
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) BatchDelJoinedSuperGroupIDs(ctx context.Context, userIDs []string) (err error) {
2023-01-29 10:31:01 +08:00
for _, userID := range userIDs {
2023-01-31 18:55:22 +08:00
if err := g.DelJoinedSuperGroupIDs(ctx, userID); err != nil {
2023-01-29 10:31:01 +08:00
return err
}
}
2023-01-31 18:55:22 +08:00
return nil
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(ctx context.Context, userID string) (err error) {
2023-01-31 18:55:22 +08:00
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return g.rcClient.TagAsDeleted(g.getJoinedSuperGroupsIDKey(userID))
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) {
2023-02-10 10:48:49 +08:00
return GetCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID)
2023-01-31 18:55:22 +08:00
if err != nil {
2023-02-10 10:48:49 +08:00
return nil, err
2023-01-31 18:55:22 +08:00
}
2023-02-10 10:48:49 +08:00
return userGroup.GroupIDs, nil
})
2023-01-31 18:55:22 +08:00
}
// groupMembersHash
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCodeUint64 uint64, err error) {
2023-02-10 15:36:25 +08:00
return GetCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
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-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) DelGroupMembersHash(ctx context.Context, groupID string) (err error) {
2023-01-31 18:55:22 +08:00
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return g.rcClient.TagAsDeleted(g.getGroupMembersHashKey(groupID))
}
// groupMemberIDs
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
2023-02-10 15:36:25 +08:00
return GetCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) {
return g.groupMember.FindMemberUserID(ctx, groupID)
})
2023-01-29 10:31:01 +08:00
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) DelGroupMemberIDs(ctx context.Context, groupID string) (err error) {
2023-01-31 18:55:22 +08:00
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return g.rcClient.TagAsDeleted(g.getGroupMemberIDsKey(groupID))
}
// JoinedGroups
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) {
2023-01-31 18:55:22 +08:00
getJoinedGroupIDList := func() (string, error) {
joinedGroupList, err := relation.GetJoinedGroupIDListByUserID(userID)
if err != nil {
return "", err
}
bytes, err := json.Marshal(joinedGroupList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "joinedGroupIDs", joinedGroupIDs)
}()
joinedGroupIDListStr, err := g.rcClient.Fetch(g.getJoinedGroupsKey(userID), time.Second*30*60, getJoinedGroupIDList)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(joinedGroupIDListStr), &joinedGroupIDs)
return joinedGroupIDs, utils.Wrap(err, "")
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) DelJoinedGroupIDs(ctx context.Context, userID string) (err error) {
2023-01-29 10:31:01 +08:00
defer func() {
2023-01-30 11:10:26 +08:00
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
2023-01-29 10:31:01 +08:00
}()
2023-01-31 18:55:22 +08:00
return g.rcClient.TagAsDeleted(g.getJoinedGroupsKey(userID))
}
// GetGroupMemberInfo
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relation.GroupMember, err error) {
2023-01-31 18:55:22 +08:00
getGroupMemberInfo := func() (string, error) {
groupMemberInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(groupID, userID)
if err != nil {
return "", err
}
bytes, err := json.Marshal(groupMemberInfo)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "groupMember", *groupMember)
}()
groupMemberInfoStr, err := g.rcClient.Fetch(g.getGroupMemberInfoKey(groupID, userID), time.Second*30*60, getGroupMemberInfo)
if err != nil {
return nil, err
}
groupMember = &relation.GroupMember{}
err = json.Unmarshal([]byte(groupMemberInfoStr), groupMember)
return groupMember, utils.Wrap(err, "")
}
2023-02-09 17:54:31 +08:00
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID, userIDs []string) (groupMember *relationTb.GroupMemberModel, err error) {
return nil, err
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relation.GroupMember, err error) {
2023-02-01 11:23:01 +08:00
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "count", count, "offset", offset, "groupID", groupID, "groupMember", groupMembers)
}()
groupMemberIDList, err := g.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return nil, err
}
if count < 0 || offset < 0 {
return nil, nil
}
var groupMemberList []*relation.GroupMember
var start, stop int32
start = offset
stop = offset + count
l := int32(len(groupMemberIDList))
if start > stop {
return nil, nil
}
if start >= l {
return nil, nil
}
if count != 0 {
if stop >= l {
stop = l
}
groupMemberIDList = groupMemberIDList[start:stop]
} else {
if l < 1000 {
stop = l
} else {
stop = 1000
}
groupMemberIDList = groupMemberIDList[start:stop]
}
for _, userID := range groupMemberIDList {
groupMember, err := g.GetGroupMemberInfo(ctx, groupID, userID)
if err != nil {
return
}
groupMembers = append(groupMembers, groupMember)
}
return groupMemberList, nil
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) DelGroupMemberInfo(ctx context.Context, groupID, userID string) (err error) {
2023-01-31 18:55:22 +08:00
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID)
}()
return g.rcClient.TagAsDeleted(g.getGroupMemberInfoKey(groupID, userID))
}
// groupMemberNum
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, groupID string) (num int, err error) {
2023-01-31 18:55:22 +08:00
getGroupMemberNum := func() (string, error) {
num, err := relation.GetGroupMemberNumByGroupID(groupID)
if err != nil {
return "", err
}
return strconv.Itoa(int(num)), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "num", num)
}()
groupMember, err := g.rcClient.Fetch(g.getGroupMemberNumKey(groupID), time.Second*30*60, getGroupMemberNum)
if err != nil {
return 0, err
}
return strconv.Atoi(groupMember)
}
2023-02-09 14:40:49 +08:00
func (g *GroupCacheRedis) DelGroupMemberNum(ctx context.Context, groupID string) (err error) {
2023-01-31 18:55:22 +08:00
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return g.rcClient.TagAsDeleted(g.getGroupMemberNumKey(groupID))
2023-01-29 10:31:01 +08:00
}
2023-02-10 15:36:25 +08:00
func (g *GroupCacheRedis) DelGroupInfo(ctx context.Context, groupID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return g.rcClient.TagAsDeleted(g.getGroupInfoKey(groupID))
}
func (g *GroupCacheRedis) DelGroupsInfo(ctx context.Context, groupIDs []string) error {
for _, groupID := range groupIDs {
if err := g.DelGroupInfo(ctx, groupID); err != nil {
return err
}
}
return nil
}