diff --git a/pkg/common/db/cache/black.go b/pkg/common/db/cache/black.go new file mode 100644 index 000000000..fda6ea04d --- /dev/null +++ b/pkg/common/db/cache/black.go @@ -0,0 +1,64 @@ +package cache + +import ( + "Open_IM/pkg/common/db/relation" + "Open_IM/pkg/common/tracelog" + "Open_IM/pkg/utils" + "context" + "encoding/json" + "github.com/dtm-labs/rockscache" + "time" +) + +const ( + blackIDsKey = "BLACK_IDS:" + blackExpireTime = time.Second * 60 * 60 * 12 +) + +type BlackCache struct { + blackDB *relation.Black + expireTime time.Duration + rcClient *rockscache.Client +} + +func NewBlackCache(blackDB *relation.Black) *BlackCache { + return &BlackCache{ + blackDB: nil, + expireTime: 0, + rcClient: nil, + } +} + +func (b *BlackCache) getBlackIDsKey(ownerUserID string) string { + return blackIDsKey + ownerUserID +} + +func (b *BlackCache) GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) { + getBlackIDList := func() (string, error) { + blackIDs, err := b.blackDB.GetBlackIDs(ctx, userID) + if err != nil { + return "", utils.Wrap(err, "") + } + bytes, err := json.Marshal(blackIDs) + if err != nil { + return "", utils.Wrap(err, "") + } + return string(bytes), nil + } + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "blackIDList", blackIDs) + }() + blackIDListStr, err := b.rcClient.Fetch(blackListCache+userID, time.Second*30*60, getBlackIDList) + if err != nil { + return nil, utils.Wrap(err, "") + } + err = json.Unmarshal([]byte(blackIDListStr), &blackIDs) + return blackIDs, utils.Wrap(err, "") +} + +func (b *BlackCache) DelBlackIDListFromCache(ctx context.Context, userID string) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ctx", ctx) + }() + return b.rcClient.TagAsDeleted(blackListCache + userID) +} diff --git a/pkg/common/db/cache/friend.go b/pkg/common/db/cache/friend.go new file mode 100644 index 000000000..65d128159 --- /dev/null +++ b/pkg/common/db/cache/friend.go @@ -0,0 +1,65 @@ +package cache + +import ( + "Open_IM/pkg/common/db/relation" + "Open_IM/pkg/common/tracelog" + "Open_IM/pkg/utils" + "context" + "encoding/json" + "github.com/dtm-labs/rockscache" + "github.com/go-redis/redis/v8" + "time" +) + +const ( + friendExpireTime = time.Second * 60 * 60 * 12 + friendIDsKey = "FRIEND_IDS:" +) + +type FriendCache struct { + friendDB *relation.Friend + expireTime time.Duration + rcClient *rockscache.Client +} + +func NewFriendCache(rdb redis.UniversalClient, friendDB *relation.Friend, options rockscache.Options) *FriendCache { + return &FriendCache{ + friendDB: friendDB, + expireTime: friendExpireTime, + rcClient: rockscache.NewClient(rdb, options), + } +} + +func (f *FriendCache) getFriendRelationKey(ownerUserID string) string { + return friendIDsKey + ownerUserID +} + +func (f *FriendCache) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) { + getFriendIDList := func() (string, error) { + friendIDList, err := f.friendDB.GetFriendIDs(ctx, ownerUserID) + if err != nil { + return "", err + } + bytes, err := json.Marshal(friendIDList) + if err != nil { + return "", utils.Wrap(err, "") + } + return string(bytes), nil + } + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID, "friendIDs", friendIDs) + }() + friendIDListStr, err := f.rcClient.Fetch(f.getFriendRelationKey(ownerUserID), f.expireTime, getFriendIDList) + if err != nil { + return nil, err + } + err = json.Unmarshal([]byte(friendIDListStr), &friendIDs) + return friendIDs, utils.Wrap(err, "") +} + +func (f *FriendCache) DelFriendIDs(ctx context.Context, ownerUserID string) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID) + }() + return f.rcClient.TagAsDeleted(f.getFriendRelationKey(ownerUserID)) +} diff --git a/pkg/common/db/cache/group.go b/pkg/common/db/cache/group.go index 50563ca88..2c9109015 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/db/cache/group.go @@ -2,6 +2,7 @@ package cache import ( "Open_IM/pkg/common/constant" + "Open_IM/pkg/common/db/localcache" "Open_IM/pkg/common/db/relation" "Open_IM/pkg/common/db/unrelation" "Open_IM/pkg/common/tracelog" @@ -39,18 +40,13 @@ type GroupCache struct { //local cache cacheGroupMtx sync.RWMutex - cacheGroupMemberUserIDs map[string]*GroupMemberIDsHash -} - -type GroupMemberIDsHash struct { - MemberListHash uint64 - UserIDs []string + cacheGroupMemberUserIDs map[string]*localcache.GroupMemberIDsHash } func NewGroupCache(rdb redis.UniversalClient, groupDB *relation.Group, groupMemberDB *relation.GroupMember, groupRequestDB *relation.GroupRequest, mongoClient *unrelation.SuperGroupMgoDB, opts rockscache.Options) *GroupCache { return &GroupCache{rcClient: rockscache.NewClient(rdb, opts), expireTime: groupExpireTime, group: groupDB, groupMember: groupMemberDB, groupRequest: groupRequestDB, redisClient: NewRedisClient(rdb), - mongoDB: mongoClient, cacheGroupMemberUserIDs: make(map[string]*GroupMemberIDsHash, 0), + mongoDB: mongoClient, cacheGroupMemberUserIDs: make(map[string]*localcache.GroupMemberIDsHash, 0), } } @@ -287,7 +283,7 @@ func (g *GroupCache) LocalGetGroupMemberIDs(ctx context.Context, groupID string) if err != nil { return nil, err } - g.cacheGroupMemberUserIDs[groupID] = &GroupMemberIDsHash{ + g.cacheGroupMemberUserIDs[groupID] = &localcache.GroupMemberIDsHash{ MemberListHash: remoteHash, UserIDs: groupMemberIDsRemote, } @@ -350,6 +346,51 @@ func (g *GroupCache) GetGroupMemberInfo(ctx context.Context, groupID, userID str return groupMember, utils.Wrap(err, "") } +func (g *GroupCache) GetGroupMembersInfo(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relation.GroupMember, err error) { + 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 +} + func (g *GroupCache) DelGroupMemberInfo(ctx context.Context, groupID, userID string) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID) diff --git a/pkg/common/db/cache/rockscache.go b/pkg/common/db/cache/rockscache.go index e17ea7c81..692e5914b 100644 --- a/pkg/common/db/cache/rockscache.go +++ b/pkg/common/db/cache/rockscache.go @@ -21,15 +21,15 @@ import ( const ( //userInfoCache = "USER_INFO_CACHE:" - friendRelationCache = "FRIEND_RELATION_CACHE:" - blackListCache = "BLACK_LIST_CACHE:" + //friendRelationCache = "FRIEND_RELATION_CACHE:" + blackListCache = "BLACK_LIST_CACHE:" //groupCache = "GROUP_CACHE:" //groupInfoCache = "GROUP_INFO_CACHE:" //groupOwnerIDCache = "GROUP_OWNER_ID:" //joinedGroupListCache = "JOINED_GROUP_LIST_CACHE:" //groupMemberInfoCache = "GROUP_MEMBER_INFO_CACHE:" //groupAllMemberInfoCache = "GROUP_ALL_MEMBER_INFO_CACHE:" - allFriendInfoCache = "ALL_FRIEND_INFO_CACHE:" + //allFriendInfoCache = "ALL_FRIEND_INFO_CACHE:" //joinedSuperGroupListCache = "JOINED_SUPER_GROUP_LIST_CACHE:" //groupMemberListHashCache = "GROUP_MEMBER_LIST_HASH_CACHE:" //groupMemberNumCache = "GROUP_MEMBER_NUM_CACHE:" diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index be5d4caa1..cda04cc86 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -137,13 +137,13 @@ func newGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, mgoClient *mongo.C groupDB := relation.NewGroupDB(db) groupMemberDB := relation.NewGroupMemberDB(db) groupRequestDB := relation.NewGroupRequest(db) - newDB := db + newDB := *db superGroupMgoDB := unrelation.NewSuperGroupMgoDB(mgoClient) database := &GroupDataBase{ groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, - db: newDB, + db: &newDB, cache: cache.NewGroupCache(rdb, groupDB, groupMemberDB, groupRequestDB, superGroupMgoDB, rockscache.Options{ RandomExpireAdjustment: 0.2, DisableCacheRead: false, diff --git a/pkg/common/db/localcache/localCache.go b/pkg/common/db/localcache/localCache.go new file mode 100644 index 000000000..9cfcec090 --- /dev/null +++ b/pkg/common/db/localcache/localCache.go @@ -0,0 +1,24 @@ +package localcache + +import "google.golang.org/grpc" + +type GroupLocalCache struct { + cache map[string]GroupMemberIDsHash + rpc *grpc.ClientConn +} + +type GroupMemberIDsHash struct { + MemberListHash uint64 + UserIDs []string +} + +func NewGroupMemberIDsLocalCache(rpc *grpc.ClientConn) GroupLocalCache { + return GroupLocalCache{ + cache: make(map[string]GroupMemberIDsHash, 0), + rpc: rpc, + } +} + +func (g *GroupMemberIDsHash) GetGroupMemberIDs(groupID string) []string { + return []string{} +} diff --git a/pkg/common/db/relation/black.go b/pkg/common/db/relation/black.go index e666ea81d..4f7e40122 100644 --- a/pkg/common/db/relation/black.go +++ b/pkg/common/db/relation/black.go @@ -20,7 +20,7 @@ type Black struct { func NewBlack(db *gorm.DB) *Black { var black Black - black.DB = db + black.DB = db.Model(&Black{}) return &black } @@ -35,7 +35,7 @@ func (b *Black) Delete(ctx context.Context, blacks []*Black) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "blacks", blacks) }() - return utils.Wrap(GroupMemberDB.Delete(blacks).Error, "") + return utils.Wrap(b.DB.Delete(blacks).Error, "") } func (b *Black) UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]interface{}) (err error) { @@ -60,7 +60,15 @@ func (b *Black) Find(ctx context.Context, blacks []*Black) (blackList []*Black, for _, black := range blacks { where = append(where, []interface{}{black.OwnerUserID, black.BlockUserID}) } - return blackList, utils.Wrap(GroupMemberDB.Where("(owner_user_id, block_user_id) in ?", where).Find(&blackList).Error, "") + return blackList, utils.Wrap(b.DB.Where("(owner_user_id, block_user_id) in ?", where).Find(&blackList).Error, "") +} + +func (b *Black) GetBlackIDs(ctx context.Context, ownerUserID string) (userIDs []string, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID, "userIDs", userIDs) + }() + err = utils.Wrap(b.DB.Where("owner_user_id = ?", ownerUserID).Pluck("block_user_id", &userIDs).Error, "") + return userIDs, err } func (b *Black) Take(ctx context.Context, ownerUserID, blockUserID string) (black *Black, err error) { diff --git a/pkg/common/db/relation/friend_model_k.go b/pkg/common/db/relation/friend_model_k.go index 519e78fec..bb70021f8 100644 --- a/pkg/common/db/relation/friend_model_k.go +++ b/pkg/common/db/relation/friend_model_k.go @@ -26,7 +26,7 @@ type FriendUser struct { func NewFriendDB(db *gorm.DB) *Friend { var friend Friend - friend.DB = initModel(db, friend) + friend.DB = db.Model(friend) return &friend } @@ -63,7 +63,7 @@ func (f *Friend) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, re defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "friendUserID", friendUserID, "remark", remark) }() - return utils.Wrap(f.DB.Model(f).Where("owner_user_id = ? and friend_user_id = ?", ownerUserID, friendUserID).Update("remark", remark).Error, "") + return utils.Wrap(f.DB.Where("owner_user_id = ? and friend_user_id = ?", ownerUserID, friendUserID).Update("remark", remark).Error, "") } func (f *Friend) FindOwnerUserID(ctx context.Context, ownerUserID string) (friends []*Friend, err error) { @@ -80,6 +80,17 @@ func (f *Friend) FindFriendUserID(ctx context.Context, friendUserID string) (fri return friends, utils.Wrap(f.DB.Where("friend_user_id = ?", friendUserID).Find(&friends).Error, "") } +func (f *Friend) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDList []string, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "friendIDList", friendIDList) + }() + err = f.DB.Where("owner_user_id=?", ownerUserID).Pluck("friend_user_id", &friendIDList).Error + if err != nil { + return nil, err + } + return friendIDList, nil +} + func (f *Friend) Take(ctx context.Context, ownerUserID, friendUserID string) (friend *Friend, err error) { friend = &Friend{} defer tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "friendUserID", friendUserID, "friend", friend)