sync: hash code

pull/857/head
withchao 2 years ago
parent b97f168753
commit 6a50db86d1

@ -16,6 +16,9 @@ package group
import ( import (
"context" "context"
"crypto/md5"
"encoding/binary"
"encoding/json"
"fmt" "fmt"
"math/big" "math/big"
"math/rand" "math/rand"
@ -73,20 +76,32 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
userRpcClient := rpcclient.NewUserRpcClient(client) userRpcClient := rpcclient.NewUserRpcClient(client)
msgRpcClient := rpcclient.NewMessageRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client)
conversationRpcClient := rpcclient.NewConversationRpcClient(client) conversationRpcClient := rpcclient.NewConversationRpcClient(client)
database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase()) var gs groupServer
pbGroup.RegisterGroupServer(server, &groupServer{ database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), gs.groupMemberHashCode)
GroupDatabase: database, gs.GroupDatabase = database
User: userRpcClient, gs.User = userRpcClient
Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) { gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
users, err := userRpcClient.GetUsersInfo(ctx, userIDs) users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
}),
conversationRpcClient: conversationRpcClient,
msgRpcClient: msgRpcClient,
}) })
gs.conversationRpcClient = conversationRpcClient
gs.msgRpcClient = msgRpcClient
//pbGroup.RegisterGroupServer(server, &groupServer{
// GroupDatabase: database,
// User: userRpcClient,
// Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
// users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
// if err != nil {
// return nil, err
// }
// return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil
// }),
// conversationRpcClient: conversationRpcClient,
// msgRpcClient: msgRpcClient,
//})
return nil return nil
} }
@ -1491,3 +1506,37 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *
resp.Total = total resp.Total = total
return resp, nil return resp, nil
} }
func (s *groupServer) groupMemberHashCode(ctx context.Context, groupID string) (uint64, error) {
userIDs, err := s.GroupDatabase.FindGroupMemberUserID(ctx, groupID)
if err != nil {
return 0, err
}
var members []*sdkws.GroupMemberFullInfo
if len(userIDs) > 0 {
resp, err := s.GetGroupMembersInfo(ctx, &pbGroup.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs})
if err != nil {
return 0, err
}
members = resp.Members
utils.Sort(userIDs, true)
}
memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string {
return e.GroupID
})
res := make([]*sdkws.GroupMemberFullInfo, 0, len(members))
for _, userID := range userIDs {
member, ok := memberMap[userID]
if !ok {
continue
}
member.AppMangerLevel = 0
res = append(res, member)
}
data, err := json.Marshal(res)
if err != nil {
return 0, err
}
sum := md5.Sum(data)
return binary.BigEndian.Uint64(sum[:]), nil
}

@ -16,11 +16,7 @@ package cache
import ( import (
"context" "context"
"crypto/md5"
"encoding/binary"
"encoding/json"
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
"strconv"
"time" "time"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
@ -99,6 +95,7 @@ type GroupCacheRedis struct {
mongoDB unrelationTb.SuperGroupModelInterface mongoDB unrelationTb.SuperGroupModelInterface
expireTime time.Duration expireTime time.Duration
rcClient *rockscache.Client rcClient *rockscache.Client
hashCode func(ctx context.Context, groupID string) (uint64, error)
} }
func NewGroupCacheRedis( func NewGroupCacheRedis(
@ -107,13 +104,16 @@ func NewGroupCacheRedis(
groupMemberDB relationTb.GroupMemberModelInterface, groupMemberDB relationTb.GroupMemberModelInterface,
groupRequestDB relationTb.GroupRequestModelInterface, groupRequestDB relationTb.GroupRequestModelInterface,
mongoClient unrelationTb.SuperGroupModelInterface, mongoClient unrelationTb.SuperGroupModelInterface,
hashCode func(ctx context.Context, groupID string) (uint64, error),
opts rockscache.Options, opts rockscache.Options,
) GroupCache { ) GroupCache {
rcClient := rockscache.NewClient(rdb, opts) rcClient := rockscache.NewClient(rdb, opts)
return &GroupCacheRedis{ return &GroupCacheRedis{
rcClient: rcClient, expireTime: groupExpireTime, rcClient: rcClient, expireTime: groupExpireTime,
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient), mongoDB: mongoClient,
hashCode: hashCode,
metaCache: NewMetaCacheRedis(rcClient),
} }
} }
@ -293,57 +293,61 @@ func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
// groupMembersHash. // groupMembersHash.
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) { func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) {
func(ctx context.Context) (uint64, error) { return g.hashCode(ctx, groupID)
userIDs, err := g.GetGroupMemberIDs(ctx, groupID) })
if err != nil {
return 0, err //return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime,
} // func(ctx context.Context) (uint64, error) {
log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs) // userIDs, err := g.GetGroupMemberIDs(ctx, groupID)
var members []*relationTb.GroupMemberModel // if err != nil {
if len(userIDs) > 0 { // return 0, err
members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs) // }
if err != nil { // log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs)
return 0, err // var members []*relationTb.GroupMemberModel
} // if len(userIDs) > 0 {
utils.Sort(userIDs, true) // members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs)
} // if err != nil {
memberMap := make(map[string]*relationTb.GroupMemberModel) // return 0, err
for i, member := range members { // }
memberMap[member.UserID] = members[i] // utils.Sort(userIDs, true)
} // }
data := make([]string, 0, len(members)*11) // memberMap := make(map[string]*relationTb.GroupMemberModel)
for _, userID := range userIDs { // for i, member := range members {
member, ok := memberMap[userID] // memberMap[member.UserID] = members[i]
if !ok { // }
continue // data := make([]string, 0, len(members)*11)
} // for _, userID := range userIDs {
data = append(data, // member, ok := memberMap[userID]
member.GroupID, // if !ok {
member.UserID, // continue
member.Nickname, // }
member.FaceURL, // data = append(data,
strconv.Itoa(int(member.RoleLevel)), // member.GroupID,
strconv.FormatInt(member.JoinTime.UnixMilli(), 10), // member.UserID,
strconv.Itoa(int(member.JoinSource)), // member.Nickname,
member.InviterUserID, // member.FaceURL,
member.OperatorUserID, // strconv.Itoa(int(member.RoleLevel)),
strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10), // strconv.FormatInt(member.JoinTime.UnixMilli(), 10),
member.Ex, // strconv.Itoa(int(member.JoinSource)),
) // member.InviterUserID,
} // member.OperatorUserID,
log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data)) // strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10),
log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data) // member.Ex,
val, err := json.Marshal(data) // )
if err != nil { // }
return 0, err // log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data))
} // log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data)
sum := md5.Sum(val) // val, err := json.Marshal(data)
code := binary.BigEndian.Uint64(sum[:]) // if err != nil {
log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members)) // return 0, err
return code, nil // }
}, // sum := md5.Sum(val)
) // code := binary.BigEndian.Uint64(sum[:])
// log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members))
// return code, nil
// },
//)
} }
func (g *GroupCacheRedis) GetGroupMemberHashMap( func (g *GroupCacheRedis) GetGroupMemberHashMap(

@ -153,7 +153,7 @@ func NewGroupDatabase(
return database return database
} }
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database) GroupDatabase { func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database, hashCode func(ctx context.Context, groupID string) (uint64, error)) GroupDatabase {
rcOptions := rockscache.NewDefaultOptions() rcOptions := rockscache.NewDefaultOptions()
rcOptions.StrongConsistency = true rcOptions.StrongConsistency = true
rcOptions.RandomExpireAdjustment = 0.2 rcOptions.RandomExpireAdjustment = 0.2
@ -170,6 +170,7 @@ func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.D
relation.NewGroupMemberDB(db), relation.NewGroupMemberDB(db),
relation.NewGroupRequest(db), relation.NewGroupRequest(db),
unrelation.NewSuperGroupMongoDriver(database), unrelation.NewSuperGroupMongoDriver(database),
hashCode,
rcOptions, rcOptions,
), ),
) )
@ -315,7 +316,7 @@ func (g *groupDatabase) FindGroupMember(
userIDs []string, userIDs []string,
roleLevels []int32, roleLevels []int32,
) (totalGroupMembers []*relationTb.GroupMemberModel, err error) { ) (totalGroupMembers []*relationTb.GroupMemberModel, err error) {
if roleLevels == nil { if len(roleLevels) == 0 {
for _, groupID := range groupIDs { for _, groupID := range groupIDs {
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
if err != nil { if err != nil {

Loading…
Cancel
Save