mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-11-05 03:42:08 +08:00
sync
This commit is contained in:
parent
a1523f47e7
commit
58c4c13cf1
@ -179,10 +179,18 @@ func (o *GroupApi) GetIncrementalGroupMemberBatch(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp.List[req.GroupID] = res
|
resp.List[req.GroupID] = res
|
||||||
changeCount += len(res.Changes) + len(res.DeleteUserIds)
|
changeCount += len(res.Insert) + len(res.Delete) + len(res.Update)
|
||||||
if changeCount >= int(res.SyncCount) {
|
if changeCount >= 200 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apiresp.GinSuccess(c, resp)
|
apiresp.GinSuccess(c, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *GroupApi) GetIncrementalGroupMemberUserIDs(c *gin.Context) {
|
||||||
|
a2r.Call(group.GroupClient.GetIncrementalGroupMemberUserIDs, o.Client, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GroupApi) GetIncrementalJoinGroupIDs(c *gin.Context) {
|
||||||
|
a2r.Call(group.GroupClient.GetIncrementalJoinGroupIDs, o.Client, c)
|
||||||
|
}
|
||||||
|
|||||||
@ -120,6 +120,8 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
groupRouterGroup.POST("/get_incremental_join_group", g.GetIncrementalJoinGroup)
|
groupRouterGroup.POST("/get_incremental_join_group", g.GetIncrementalJoinGroup)
|
||||||
groupRouterGroup.POST("/get_incremental_group_member", g.GetIncrementalGroupMember)
|
groupRouterGroup.POST("/get_incremental_group_member", g.GetIncrementalGroupMember)
|
||||||
groupRouterGroup.POST("/get_incremental_group_member_batch", g.GetIncrementalGroupMemberBatch)
|
groupRouterGroup.POST("/get_incremental_group_member_batch", g.GetIncrementalGroupMemberBatch)
|
||||||
|
groupRouterGroup.POST("/get_incremental_group_member_user_ids", g.GetIncrementalGroupMemberUserIDs)
|
||||||
|
groupRouterGroup.POST("/get_incremental_join_group_ids", g.GetIncrementalJoinGroupIDs)
|
||||||
}
|
}
|
||||||
// certificate
|
// certificate
|
||||||
authRouterGroup := r.Group("/auth")
|
authRouterGroup := r.Group("/auth")
|
||||||
|
|||||||
@ -64,9 +64,6 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
if config.RpcConfig.FriendSyncCount < 1 {
|
|
||||||
config.RpcConfig.FriendSyncCount = constant.MaxSyncPullNumber
|
|
||||||
}
|
|
||||||
mgocli, err := mongoutil.NewMongoDB(ctx, config.MongodbConfig.Build())
|
mgocli, err := mongoutil.NewMongoDB(ctx, config.MongodbConfig.Build())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -25,14 +25,14 @@ func (s *friendServer) GetIncrementalFriends(ctx context.Context, req *relation.
|
|||||||
return s.getFriend(ctx, req.UserID, ids)
|
return s.getFriend(ctx, req.UserID, ids)
|
||||||
},
|
},
|
||||||
ID: func(elem *sdkws.FriendInfo) string { return elem.FriendUser.UserID },
|
ID: func(elem *sdkws.FriendInfo) string { return elem.FriendUser.UserID },
|
||||||
Resp: func(version *model.VersionLog, delIDs []string, list []*sdkws.FriendInfo, full bool) *relation.GetIncrementalFriendsResp {
|
Resp: func(version *model.VersionLog, deleteIds []string, insertList, updateList []*sdkws.FriendInfo, full bool) *relation.GetIncrementalFriendsResp {
|
||||||
return &relation.GetIncrementalFriendsResp{
|
return &relation.GetIncrementalFriendsResp{
|
||||||
VersionID: version.ID.Hex(),
|
VersionID: version.ID.Hex(),
|
||||||
Version: uint64(version.Version),
|
Version: uint64(version.Version),
|
||||||
Full: full,
|
Full: full,
|
||||||
SyncCount: uint32(s.config.RpcConfig.FriendSyncCount),
|
Delete: deleteIds,
|
||||||
DeleteUserIds: delIDs,
|
Insert: insertList,
|
||||||
Changes: list,
|
Update: updateList,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,9 +77,6 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
if config.RpcConfig.GroupSyncCount <= 0 {
|
|
||||||
config.RpcConfig.GroupSyncCount = constant.MaxSyncPullNumber
|
|
||||||
}
|
|
||||||
mgocli, err := mongoutil.NewMongoDB(ctx, config.MongodbConfig.Build())
|
mgocli, err := mongoutil.NewMongoDB(ctx, config.MongodbConfig.Build())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -104,7 +101,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
|||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client, config.Share.RpcRegisterName.Msg)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config.Share.RpcRegisterName.Msg)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config.Share.RpcRegisterName.Conversation)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config.Share.RpcRegisterName.Conversation)
|
||||||
var gs groupServer
|
var gs groupServer
|
||||||
database := controller.NewGroupDatabase(rdb, &config.LocalCacheConfig, groupDB, groupMemberDB, groupRequestDB, mgocli.GetTx(), grouphash.NewGroupHashFromGroupServer(&gs), config.RpcConfig.GroupSyncCount)
|
database := controller.NewGroupDatabase(rdb, &config.LocalCacheConfig, groupDB, groupMemberDB, groupRequestDB, mgocli.GetTx(), grouphash.NewGroupHashFromGroupServer(&gs))
|
||||||
gs.db = database
|
gs.db = database
|
||||||
gs.user = userRpcClient
|
gs.user = userRpcClient
|
||||||
gs.notification = NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, config, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
gs.notification = NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, config, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||||
|
|||||||
@ -2,6 +2,9 @@ package group
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/incrversion"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/incrversion"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
@ -9,6 +12,57 @@ import (
|
|||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *groupServer) idHash(ids []string) uint64 {
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
data, _ := json.Marshal(ids)
|
||||||
|
sum := md5.Sum(data)
|
||||||
|
return binary.BigEndian.Uint64(sum[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupServer) GetIncrementalGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetIncrementalGroupMemberUserIDsReq) (*pbgroup.GetIncrementalGroupMemberUserIDsResp, error) {
|
||||||
|
vl, err := s.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userIDs, err := s.db.FindGroupMemberUserID(ctx, req.GroupID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
idHash := s.idHash(userIDs)
|
||||||
|
if req.IdHash == idHash {
|
||||||
|
userIDs = nil
|
||||||
|
}
|
||||||
|
return &pbgroup.GetIncrementalGroupMemberUserIDsResp{
|
||||||
|
Version: idHash,
|
||||||
|
VersionID: vl.ID.Hex(),
|
||||||
|
Equal: req.IdHash == idHash,
|
||||||
|
UserIDs: userIDs,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupServer) GetIncrementalJoinGroupIDs(ctx context.Context, req *pbgroup.GetIncrementalJoinGroupIDsReq) (*pbgroup.GetIncrementalJoinGroupIDsResp, error) {
|
||||||
|
vl, err := s.db.FindMaxJoinGroupVersionCache(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
groupIDs, err := s.db.FindJoinGroupID(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
idHash := s.idHash(groupIDs)
|
||||||
|
if req.IdHash == idHash {
|
||||||
|
groupIDs = nil
|
||||||
|
}
|
||||||
|
return &pbgroup.GetIncrementalJoinGroupIDsResp{
|
||||||
|
Version: idHash,
|
||||||
|
VersionID: vl.ID.Hex(),
|
||||||
|
Equal: req.IdHash == idHash,
|
||||||
|
GroupIDs: groupIDs,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgroup.GetIncrementalGroupMemberReq) (*pbgroup.GetIncrementalGroupMemberResp, error) {
|
func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgroup.GetIncrementalGroupMemberReq) (*pbgroup.GetIncrementalGroupMemberResp, error) {
|
||||||
opt := incrversion.Option[*sdkws.GroupMemberFullInfo, pbgroup.GetIncrementalGroupMemberResp]{
|
opt := incrversion.Option[*sdkws.GroupMemberFullInfo, pbgroup.GetIncrementalGroupMemberResp]{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
@ -21,14 +75,14 @@ func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgrou
|
|||||||
return s.getGroupMembersInfo(ctx, req.GroupID, ids)
|
return s.getGroupMembersInfo(ctx, req.GroupID, ids)
|
||||||
},
|
},
|
||||||
ID: func(elem *sdkws.GroupMemberFullInfo) string { return elem.UserID },
|
ID: func(elem *sdkws.GroupMemberFullInfo) string { return elem.UserID },
|
||||||
Resp: func(version *model.VersionLog, delIDs []string, list []*sdkws.GroupMemberFullInfo, full bool) *pbgroup.GetIncrementalGroupMemberResp {
|
Resp: func(version *model.VersionLog, delIDs []string, insertList, updateList []*sdkws.GroupMemberFullInfo, full bool) *pbgroup.GetIncrementalGroupMemberResp {
|
||||||
return &pbgroup.GetIncrementalGroupMemberResp{
|
return &pbgroup.GetIncrementalGroupMemberResp{
|
||||||
VersionID: version.ID.Hex(),
|
VersionID: version.ID.Hex(),
|
||||||
Version: uint64(version.Version),
|
Version: uint64(version.Version),
|
||||||
Full: full,
|
Full: full,
|
||||||
SyncCount: uint32(s.config.RpcConfig.GroupSyncCount),
|
Delete: delIDs,
|
||||||
DeleteUserIds: delIDs,
|
Insert: insertList,
|
||||||
Changes: list,
|
Update: updateList,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -48,14 +102,14 @@ func (s *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.
|
|||||||
CacheMaxVersion: s.db.FindMaxJoinGroupVersionCache,
|
CacheMaxVersion: s.db.FindMaxJoinGroupVersionCache,
|
||||||
Find: s.getGroupsInfo,
|
Find: s.getGroupsInfo,
|
||||||
ID: func(elem *sdkws.GroupInfo) string { return elem.GroupID },
|
ID: func(elem *sdkws.GroupInfo) string { return elem.GroupID },
|
||||||
Resp: func(version *model.VersionLog, delIDs []string, list []*sdkws.GroupInfo, full bool) *pbgroup.GetIncrementalJoinGroupResp {
|
Resp: func(version *model.VersionLog, delIDs []string, insertList, updateList []*sdkws.GroupInfo, full bool) *pbgroup.GetIncrementalJoinGroupResp {
|
||||||
return &pbgroup.GetIncrementalJoinGroupResp{
|
return &pbgroup.GetIncrementalJoinGroupResp{
|
||||||
VersionID: version.ID.Hex(),
|
VersionID: version.ID.Hex(),
|
||||||
Version: uint64(version.Version),
|
Version: uint64(version.Version),
|
||||||
Full: full,
|
Full: full,
|
||||||
SyncCount: uint32(s.config.RpcConfig.GroupSyncCount),
|
Delete: delIDs,
|
||||||
DeleteGroupIds: delIDs,
|
Insert: insertList,
|
||||||
Changes: list,
|
Update: updateList,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ type Option[A, B any] struct {
|
|||||||
//SortID func(ctx context.Context, dId string) ([]string, error)
|
//SortID func(ctx context.Context, dId string) ([]string, error)
|
||||||
Find func(ctx context.Context, ids []string) ([]A, error)
|
Find func(ctx context.Context, ids []string) ([]A, error)
|
||||||
ID func(elem A) string
|
ID func(elem A) string
|
||||||
Resp func(version *model.VersionLog, delIDs []string, list []A, full bool) *B
|
Resp func(version *model.VersionLog, deleteIds []string, insertList, updateList []A, full bool) *B
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Option[A, B]) newError(msg string) error {
|
func (o *Option[A, B]) newError(msg string) error {
|
||||||
@ -130,31 +129,28 @@ func (o *Option[A, B]) Build() (*B, error) {
|
|||||||
panic(fmt.Errorf("undefined tag %d", tag))
|
panic(fmt.Errorf("undefined tag %d", tag))
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
deleteIDs []string
|
insertIds []string
|
||||||
changeIDs []string
|
deleteIds []string
|
||||||
|
updateIds []string
|
||||||
)
|
)
|
||||||
if full {
|
if !full {
|
||||||
//changeIDs, err = o.SortID(o.Ctx, o.VersionKey)
|
insertIds, deleteIds, updateIds = version.DeleteAndChangeIDs()
|
||||||
//if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
//}
|
|
||||||
} else {
|
|
||||||
deleteIDs, changeIDs = version.DeleteAndChangeIDs()
|
|
||||||
}
|
}
|
||||||
var list []A
|
var (
|
||||||
if len(changeIDs) > 0 {
|
insertList []A
|
||||||
list, err = o.Find(o.Ctx, changeIDs)
|
updateList []A
|
||||||
|
)
|
||||||
|
if len(insertIds) > 0 {
|
||||||
|
insertList, err = o.Find(o.Ctx, insertIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if (!full) && o.ID != nil && len(changeIDs) != len(list) {
|
}
|
||||||
foundIDs := datautil.SliceSetAny(list, o.ID)
|
if len(updateIds) > 0 {
|
||||||
for _, id := range changeIDs {
|
updateList, err = o.Find(o.Ctx, updateIds)
|
||||||
if _, ok := foundIDs[id]; !ok {
|
if err != nil {
|
||||||
deleteIDs = append(deleteIDs, id)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return o.Resp(version, deleteIds, insertList, updateList, full), nil
|
||||||
}
|
|
||||||
return o.Resp(version, deleteIDs, list, full), nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -245,7 +245,6 @@ type Friend struct {
|
|||||||
Ports []int `mapstructure:"ports"`
|
Ports []int `mapstructure:"ports"`
|
||||||
} `mapstructure:"rpc"`
|
} `mapstructure:"rpc"`
|
||||||
Prometheus Prometheus `mapstructure:"prometheus"`
|
Prometheus Prometheus `mapstructure:"prometheus"`
|
||||||
FriendSyncCount int `mapstructure:"friendSyncCount"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Group struct {
|
type Group struct {
|
||||||
@ -255,7 +254,6 @@ type Group struct {
|
|||||||
Ports []int `mapstructure:"ports"`
|
Ports []int `mapstructure:"ports"`
|
||||||
} `mapstructure:"rpc"`
|
} `mapstructure:"rpc"`
|
||||||
Prometheus Prometheus `mapstructure:"prometheus"`
|
Prometheus Prometheus `mapstructure:"prometheus"`
|
||||||
GroupSyncCount int `mapstructure:"groupSyncCount"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Msg struct {
|
type Msg struct {
|
||||||
|
|||||||
3
pkg/common/storage/cache/redis/group.go
vendored
3
pkg/common/storage/cache/redis/group.go
vendored
@ -45,7 +45,6 @@ type GroupCacheRedis struct {
|
|||||||
expireTime time.Duration
|
expireTime time.Duration
|
||||||
rcClient *rockscache.Client
|
rcClient *rockscache.Client
|
||||||
groupHash cache.GroupHash
|
groupHash cache.GroupHash
|
||||||
syncCount int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGroupCacheRedis(
|
func NewGroupCacheRedis(
|
||||||
@ -56,7 +55,6 @@ func NewGroupCacheRedis(
|
|||||||
groupRequestDB database.GroupRequest,
|
groupRequestDB database.GroupRequest,
|
||||||
hashCode cache.GroupHash,
|
hashCode cache.GroupHash,
|
||||||
opts *rockscache.Options,
|
opts *rockscache.Options,
|
||||||
syncCount int,
|
|
||||||
) cache.GroupCache {
|
) cache.GroupCache {
|
||||||
batchHandler := NewBatchDeleterRedis(rdb, opts, []string{localCache.Group.Topic})
|
batchHandler := NewBatchDeleterRedis(rdb, opts, []string{localCache.Group.Topic})
|
||||||
g := localCache.Group
|
g := localCache.Group
|
||||||
@ -70,7 +68,6 @@ func NewGroupCacheRedis(
|
|||||||
groupMemberDB: groupMemberDB,
|
groupMemberDB: groupMemberDB,
|
||||||
groupRequestDB: groupRequestDB,
|
groupRequestDB: groupRequestDB,
|
||||||
groupHash: hashCode,
|
groupHash: hashCode,
|
||||||
syncCount: syncCount,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,6 +117,8 @@ type GroupDatabase interface {
|
|||||||
FindMaxJoinGroupVersionCache(ctx context.Context, userID string) (*model.VersionLog, error)
|
FindMaxJoinGroupVersionCache(ctx context.Context, userID string) (*model.VersionLog, error)
|
||||||
|
|
||||||
SearchJoinGroup(ctx context.Context, userID string, keyword string, pagination pagination.Pagination) (int64, []*model.Group, error)
|
SearchJoinGroup(ctx context.Context, userID string, keyword string, pagination pagination.Pagination) (int64, []*model.Group, error)
|
||||||
|
|
||||||
|
FindJoinGroupID(ctx context.Context, userID string) ([]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGroupDatabase(
|
func NewGroupDatabase(
|
||||||
@ -127,14 +129,13 @@ func NewGroupDatabase(
|
|||||||
groupRequestDB database.GroupRequest,
|
groupRequestDB database.GroupRequest,
|
||||||
ctxTx tx.Tx,
|
ctxTx tx.Tx,
|
||||||
groupHash cache.GroupHash,
|
groupHash cache.GroupHash,
|
||||||
syncCount int,
|
|
||||||
) GroupDatabase {
|
) GroupDatabase {
|
||||||
return &groupDatabase{
|
return &groupDatabase{
|
||||||
groupDB: groupDB,
|
groupDB: groupDB,
|
||||||
groupMemberDB: groupMemberDB,
|
groupMemberDB: groupMemberDB,
|
||||||
groupRequestDB: groupRequestDB,
|
groupRequestDB: groupRequestDB,
|
||||||
ctxTx: ctxTx,
|
ctxTx: ctxTx,
|
||||||
cache: redis2.NewGroupCacheRedis(rdb, localCache, groupDB, groupMemberDB, groupRequestDB, groupHash, redis2.GetRocksCacheOptions(), syncCount),
|
cache: redis2.NewGroupCacheRedis(rdb, localCache, groupDB, groupMemberDB, groupRequestDB, groupHash, redis2.GetRocksCacheOptions()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,6 +147,10 @@ type groupDatabase struct {
|
|||||||
cache cache.GroupCache
|
cache cache.GroupCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *groupDatabase) FindJoinGroupID(ctx context.Context, userID string) ([]string, error) {
|
||||||
|
return g.cache.GetJoinedGroupIDs(ctx, userID)
|
||||||
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupMember, error) {
|
func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupMember, error) {
|
||||||
return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||||
}
|
}
|
||||||
@ -243,7 +248,7 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, userID := range userIDs {
|
for _, userID := range userIDs {
|
||||||
if err := g.groupMemberDB.JoinGroupIncrVersion(ctx, userID, []string{groupID}, false); err != nil {
|
if err := g.groupMemberDB.JoinGroupIncrVersion(ctx, userID, []string{groupID}, model.VersionStateUpdate); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +281,7 @@ func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, delete
|
|||||||
}
|
}
|
||||||
c = c.DelMaxJoinGroupVersion(userIDs...)
|
c = c.DelMaxJoinGroupVersion(userIDs...)
|
||||||
if len(userIDs) > 0 {
|
if len(userIDs) > 0 {
|
||||||
if err := g.groupMemberDB.JoinGroupIncrVersion(ctx, groupID, userIDs, true); err != nil {
|
if err := g.groupMemberDB.JoinGroupIncrVersion(ctx, groupID, userIDs, model.VersionStateDelete); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ type GroupMember interface {
|
|||||||
TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error)
|
TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error)
|
||||||
FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error)
|
FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error)
|
||||||
IsUpdateRoleLevel(data map[string]any) bool
|
IsUpdateRoleLevel(data map[string]any) bool
|
||||||
JoinGroupIncrVersion(ctx context.Context, userID string, groupIDs []string, deleted bool) error
|
JoinGroupIncrVersion(ctx context.Context, userID string, groupIDs []string, state int32) error
|
||||||
FindMemberIncrVersion(ctx context.Context, groupID string, version uint, limit int) (*model.VersionLog, error)
|
FindMemberIncrVersion(ctx context.Context, groupID string, version uint, limit int) (*model.VersionLog, error)
|
||||||
FindJoinIncrVersion(ctx context.Context, userID string, version uint, limit int) (*model.VersionLog, error)
|
FindJoinIncrVersion(ctx context.Context, userID string, version uint, limit int) (*model.VersionLog, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ func (f *FriendMgo) Create(ctx context.Context, friends []*model.Friend) error {
|
|||||||
mp[friend.OwnerUserID] = append(mp[friend.OwnerUserID], friend.FriendUserID)
|
mp[friend.OwnerUserID] = append(mp[friend.OwnerUserID], friend.FriendUserID)
|
||||||
}
|
}
|
||||||
for ownerUserID, friendUserIDs := range mp {
|
for ownerUserID, friendUserIDs := range mp {
|
||||||
if err := f.owner.IncrVersion(ctx, ownerUserID, friendUserIDs, false); err != nil {
|
if err := f.owner.IncrVersion(ctx, ownerUserID, friendUserIDs, model.VersionStateInsert); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ func (f *FriendMgo) Delete(ctx context.Context, ownerUserID string, friendUserID
|
|||||||
return mongoutil.IncrVersion(func() error {
|
return mongoutil.IncrVersion(func() error {
|
||||||
return mongoutil.DeleteOne(ctx, f.coll, filter)
|
return mongoutil.DeleteOne(ctx, f.coll, filter)
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return f.owner.IncrVersion(ctx, ownerUserID, friendUserIDs, true)
|
return f.owner.IncrVersion(ctx, ownerUserID, friendUserIDs, model.VersionStateDelete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ func (f *FriendMgo) UpdateByMap(ctx context.Context, ownerUserID string, friendU
|
|||||||
return mongoutil.IncrVersion(func() error {
|
return mongoutil.IncrVersion(func() error {
|
||||||
return mongoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": args}, true)
|
return mongoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": args}, true)
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return f.owner.IncrVersion(ctx, ownerUserID, []string{friendUserID}, false)
|
return f.owner.IncrVersion(ctx, ownerUserID, []string{friendUserID}, model.VersionStateUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ func (f *FriendMgo) UpdateFriends(ctx context.Context, ownerUserID string, frien
|
|||||||
return mongoutil.IncrVersion(func() error {
|
return mongoutil.IncrVersion(func() error {
|
||||||
return mongoutil.Ignore(mongoutil.UpdateMany(ctx, f.coll, filter, update))
|
return mongoutil.Ignore(mongoutil.UpdateMany(ctx, f.coll, filter, update))
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return f.owner.IncrVersion(ctx, ownerUserID, friendUserIDs, false)
|
return f.owner.IncrVersion(ctx, ownerUserID, friendUserIDs, model.VersionStateUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,7 @@ func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*model.Group
|
|||||||
gms[member.GroupID] = append(gms[member.GroupID], member.UserID)
|
gms[member.GroupID] = append(gms[member.GroupID], member.UserID)
|
||||||
}
|
}
|
||||||
for groupID, userIDs := range gms {
|
for groupID, userIDs := range gms {
|
||||||
if err := g.member.IncrVersion(ctx, groupID, userIDs, false); err != nil {
|
if err := g.member.IncrVersion(ctx, groupID, userIDs, model.VersionStateInsert); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*model.Group
|
|||||||
gms[member.UserID] = append(gms[member.UserID], member.GroupID)
|
gms[member.UserID] = append(gms[member.UserID], member.GroupID)
|
||||||
}
|
}
|
||||||
for userID, groupIDs := range gms {
|
for userID, groupIDs := range gms {
|
||||||
if err := g.join.IncrVersion(ctx, userID, groupIDs, false); err != nil {
|
if err := g.join.IncrVersion(ctx, userID, groupIDs, model.VersionStateInsert); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,12 +97,12 @@ func (g *GroupMemberMgo) Delete(ctx context.Context, groupID string, userIDs []s
|
|||||||
return mongoutil.IncrVersion(func() error {
|
return mongoutil.IncrVersion(func() error {
|
||||||
return mongoutil.DeleteMany(ctx, g.coll, filter)
|
return mongoutil.DeleteMany(ctx, g.coll, filter)
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return g.member.IncrVersion(ctx, groupID, userIDs, true)
|
return g.member.IncrVersion(ctx, groupID, userIDs, model.VersionStateDelete)
|
||||||
}, func() error {
|
}, func() error {
|
||||||
if len(userIDs) == 0 {
|
if len(userIDs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return g.member.IncrVersion(ctx, groupID, userIDs, true)
|
return g.member.IncrVersion(ctx, groupID, userIDs, model.VersionStateDelete)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,9 +110,9 @@ func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, us
|
|||||||
return mongoutil.IncrVersion(func() error {
|
return mongoutil.IncrVersion(func() error {
|
||||||
return g.Update(ctx, groupID, userID, bson.M{"role_level": roleLevel})
|
return g.Update(ctx, groupID, userID, bson.M{"role_level": roleLevel})
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return g.member.IncrVersion(ctx, groupID, []string{userID}, true)
|
return g.member.IncrVersion(ctx, groupID, []string{userID}, model.VersionStateUpdate)
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return g.join.IncrVersion(ctx, groupID, []string{userID}, true)
|
return g.join.IncrVersion(ctx, groupID, []string{userID}, model.VersionStateUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ func (g *GroupMemberMgo) Update(ctx context.Context, groupID string, userID stri
|
|||||||
return mongoutil.IncrVersion(func() error {
|
return mongoutil.IncrVersion(func() error {
|
||||||
return mongoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": data}, true)
|
return mongoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": data}, true)
|
||||||
}, func() error {
|
}, func() error {
|
||||||
return g.member.IncrVersion(ctx, groupID, []string{userID}, false)
|
return g.member.IncrVersion(ctx, groupID, []string{userID}, model.VersionStateUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,8 +174,8 @@ func (g *GroupMemberMgo) IsUpdateRoleLevel(data map[string]any) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupMemberMgo) JoinGroupIncrVersion(ctx context.Context, userID string, groupIDs []string, deleted bool) error {
|
func (g *GroupMemberMgo) JoinGroupIncrVersion(ctx context.Context, userID string, groupIDs []string, state int32) error {
|
||||||
return g.join.IncrVersion(ctx, userID, groupIDs, deleted)
|
return g.join.IncrVersion(ctx, userID, groupIDs, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupMemberMgo) FindMemberIncrVersion(ctx context.Context, groupID string, version uint, limit int) (*model.VersionLog, error) {
|
func (g *GroupMemberMgo) FindMemberIncrVersion(ctx context.Context, groupID string, version uint, limit int) (*model.VersionLog, error) {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ func (l *VersionLogMgo) initIndex(ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *VersionLogMgo) IncrVersion(ctx context.Context, dId string, eIds []string, deleted bool) error {
|
func (l *VersionLogMgo) IncrVersion(ctx context.Context, dId string, eIds []string, state int32) error {
|
||||||
if len(eIds) == 0 {
|
if len(eIds) == 0 {
|
||||||
return errs.ErrArgs.WrapMsg("elem id is empty", "dId", dId)
|
return errs.ErrArgs.WrapMsg("elem id is empty", "dId", dId)
|
||||||
}
|
}
|
||||||
@ -44,19 +44,19 @@ func (l *VersionLogMgo) IncrVersion(ctx context.Context, dId string, eIds []stri
|
|||||||
return errs.ErrArgs.WrapMsg("elem id is duplicate", "dId", dId, "eIds", eIds)
|
return errs.ErrArgs.WrapMsg("elem id is duplicate", "dId", dId, "eIds", eIds)
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
res, err := l.writeLogBatch(ctx, dId, eIds, deleted, now)
|
res, err := l.writeLogBatch(ctx, dId, eIds, state, now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if res.MatchedCount > 0 {
|
if res.MatchedCount > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if _, err := l.initDoc(ctx, dId, eIds, deleted, now); err == nil {
|
if _, err := l.initDoc(ctx, dId, eIds, state, now); err == nil {
|
||||||
return nil
|
return nil
|
||||||
} else if !mongo.IsDuplicateKeyError(err) {
|
} else if !mongo.IsDuplicateKeyError(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if res, err := l.writeLogBatch(ctx, dId, eIds, deleted, now); err != nil {
|
if res, err := l.writeLogBatch(ctx, dId, eIds, state, now); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if res.MatchedCount == 0 {
|
} else if res.MatchedCount == 0 {
|
||||||
return errs.ErrInternalServer.WrapMsg("mongodb return value that should not occur", "coll", l.coll.Name(), "dId", dId, "eIds", eIds)
|
return errs.ErrInternalServer.WrapMsg("mongodb return value that should not occur", "coll", l.coll.Name(), "dId", dId, "eIds", eIds)
|
||||||
@ -64,7 +64,7 @@ func (l *VersionLogMgo) IncrVersion(ctx context.Context, dId string, eIds []stri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *VersionLogMgo) initDoc(ctx context.Context, dId string, eIds []string, deleted bool, now time.Time) (*model.VersionLogTable, error) {
|
func (l *VersionLogMgo) initDoc(ctx context.Context, dId string, eIds []string, state int32, now time.Time) (*model.VersionLogTable, error) {
|
||||||
wl := model.VersionLogTable{
|
wl := model.VersionLogTable{
|
||||||
ID: primitive.NewObjectID(),
|
ID: primitive.NewObjectID(),
|
||||||
DID: dId,
|
DID: dId,
|
||||||
@ -76,7 +76,7 @@ func (l *VersionLogMgo) initDoc(ctx context.Context, dId string, eIds []string,
|
|||||||
for _, eId := range eIds {
|
for _, eId := range eIds {
|
||||||
wl.Logs = append(wl.Logs, model.VersionLogElem{
|
wl.Logs = append(wl.Logs, model.VersionLogElem{
|
||||||
EID: eId,
|
EID: eId,
|
||||||
Deleted: deleted,
|
State: state,
|
||||||
Version: database.FirstVersion,
|
Version: database.FirstVersion,
|
||||||
LastUpdate: now,
|
LastUpdate: now,
|
||||||
})
|
})
|
||||||
@ -85,7 +85,7 @@ func (l *VersionLogMgo) initDoc(ctx context.Context, dId string, eIds []string,
|
|||||||
return &wl, err
|
return &wl, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *VersionLogMgo) writeLogBatch(ctx context.Context, dId string, eIds []string, deleted bool, now time.Time) (*mongo.UpdateResult, error) {
|
func (l *VersionLogMgo) writeLogBatch(ctx context.Context, dId string, eIds []string, state int32, now time.Time) (*mongo.UpdateResult, error) {
|
||||||
if eIds == nil {
|
if eIds == nil {
|
||||||
eIds = []string{}
|
eIds = []string{}
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ func (l *VersionLogMgo) writeLogBatch(ctx context.Context, dId string, eIds []st
|
|||||||
elems = append(elems, bson.M{
|
elems = append(elems, bson.M{
|
||||||
"e_id": eId,
|
"e_id": eId,
|
||||||
"version": "$version",
|
"version": "$version",
|
||||||
"deleted": deleted,
|
"state": state,
|
||||||
"last_update": now,
|
"last_update": now,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ func (l *VersionLogMgo) FindChangeLog(ctx context.Context, dId string, version u
|
|||||||
} else if !errors.Is(err, mongo.ErrNoDocuments) {
|
} else if !errors.Is(err, mongo.ErrNoDocuments) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if res, err := l.initDoc(ctx, dId, nil, false, time.Now()); err == nil {
|
if res, err := l.initDoc(ctx, dId, nil, 0, time.Now()); err == nil {
|
||||||
return res.VersionLog(), nil
|
return res.VersionLog(), nil
|
||||||
} else if mongo.IsDuplicateKeyError(err) {
|
} else if mongo.IsDuplicateKeyError(err) {
|
||||||
return l.findChangeLog(ctx, dId, version, limit)
|
return l.findChangeLog(ctx, dId, version, limit)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type VersionLog interface {
|
type VersionLog interface {
|
||||||
IncrVersion(ctx context.Context, dId string, eIds []string, deleted bool) error
|
IncrVersion(ctx context.Context, dId string, eIds []string, state int32) error
|
||||||
FindChangeLog(ctx context.Context, dId string, version uint, limit int) (*model.VersionLog, error)
|
FindChangeLog(ctx context.Context, dId string, version uint, limit int) (*model.VersionLog, error)
|
||||||
DeleteAfterUnchangedLog(ctx context.Context, deadline time.Time) error
|
DeleteAfterUnchangedLog(ctx context.Context, deadline time.Time) error
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,22 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/openimsdk/tools/log"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VersionStateInsert = iota + 1
|
||||||
|
VersionStateDelete
|
||||||
|
VersionStateUpdate
|
||||||
|
)
|
||||||
|
|
||||||
type VersionLogElem struct {
|
type VersionLogElem struct {
|
||||||
EID string `bson:"e_id"`
|
EID string `bson:"e_id"`
|
||||||
Deleted bool `bson:"deleted"`
|
State int32 `bson:"state"`
|
||||||
Version uint `bson:"version"`
|
Version uint `bson:"version"`
|
||||||
LastUpdate time.Time `bson:"last_update"`
|
LastUpdate time.Time `bson:"last_update"`
|
||||||
}
|
}
|
||||||
@ -43,12 +52,17 @@ type VersionLog struct {
|
|||||||
LogLen int `bson:"log_len"`
|
LogLen int `bson:"log_len"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VersionLog) DeleteAndChangeIDs() (delIds []string, changeIds []string) {
|
func (v *VersionLog) DeleteAndChangeIDs() (insertIds, deleteIds, updateIds []string) {
|
||||||
for _, l := range v.Logs {
|
for _, l := range v.Logs {
|
||||||
if l.Deleted {
|
switch l.State {
|
||||||
delIds = append(delIds, l.EID)
|
case VersionStateInsert:
|
||||||
} else {
|
insertIds = append(insertIds, l.EID)
|
||||||
changeIds = append(changeIds, l.EID)
|
case VersionStateDelete:
|
||||||
|
deleteIds = append(deleteIds, l.EID)
|
||||||
|
case VersionStateUpdate:
|
||||||
|
updateIds = append(updateIds, l.EID)
|
||||||
|
default:
|
||||||
|
log.ZError(context.Background(), "invalid version status found", errors.New("dirty database data"), "objID", v.ID.Hex(), "did", v.DID, "elem", l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user