mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-12-21 22:37:13 +08:00
friend incr sync
This commit is contained in:
parent
1f02bdc267
commit
8e37a417db
6
go.mod
6
go.mod
@ -178,6 +178,6 @@ require (
|
|||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
//replace (
|
replace (
|
||||||
// github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol
|
github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol
|
||||||
//)
|
)
|
||||||
|
|||||||
@ -90,6 +90,11 @@ func (o *FriendApi) GetFriendIDs(c *gin.Context) {
|
|||||||
func (o *FriendApi) GetSpecifiedFriendsInfo(c *gin.Context) {
|
func (o *FriendApi) GetSpecifiedFriendsInfo(c *gin.Context) {
|
||||||
a2r.Call(friend.FriendClient.GetSpecifiedFriendsInfo, o.Client, c)
|
a2r.Call(friend.FriendClient.GetSpecifiedFriendsInfo, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *FriendApi) UpdateFriends(c *gin.Context) {
|
func (o *FriendApi) UpdateFriends(c *gin.Context) {
|
||||||
a2r.Call(friend.FriendClient.UpdateFriends, o.Client, c)
|
a2r.Call(friend.FriendClient.UpdateFriends, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *FriendApi) GetIncrementalFriends(c *gin.Context) {
|
||||||
|
a2r.Call(friend.FriendClient.GetIncrementalFriends, o.Client, c)
|
||||||
|
}
|
||||||
|
|||||||
@ -86,6 +86,7 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
friendRouterGroup.POST("/get_friend_id", f.GetFriendIDs)
|
friendRouterGroup.POST("/get_friend_id", f.GetFriendIDs)
|
||||||
friendRouterGroup.POST("/get_specified_friends_info", f.GetSpecifiedFriendsInfo)
|
friendRouterGroup.POST("/get_specified_friends_info", f.GetSpecifiedFriendsInfo)
|
||||||
friendRouterGroup.POST("/update_friends", f.UpdateFriends)
|
friendRouterGroup.POST("/update_friends", f.UpdateFriends)
|
||||||
|
friendRouterGroup.POST("/get_incremental_friends", f.GetIncrementalFriends)
|
||||||
}
|
}
|
||||||
g := NewGroupApi(*groupRpc)
|
g := NewGroupApi(*groupRpc)
|
||||||
groupRouterGroup := r.Group("/group")
|
groupRouterGroup := r.Group("/group")
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/dataver"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/dataver"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
pbfriend "github.com/openimsdk/protocol/friend"
|
pbfriend "github.com/openimsdk/protocol/friend"
|
||||||
@ -21,7 +22,10 @@ func (s *friendServer) sortFriendUserIDsHash(userIDs []string) uint64 {
|
|||||||
return binary.BigEndian.Uint64(sum[:])
|
return binary.BigEndian.Uint64(sum[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) IncrSyncFriends(ctx context.Context, req *pbfriend.IncrSyncFriendsReq) (*pbfriend.IncrSyncFriendsResp, error) {
|
func (s *friendServer) GetIncrementalFriends(ctx context.Context, req *pbfriend.GetIncrementalFriendsReq) (*pbfriend.GetIncrementalFriendsResp, error) {
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
var limit int
|
var limit int
|
||||||
if req.Version > 0 {
|
if req.Version > 0 {
|
||||||
limit = s.config.RpcConfig.FriendSyncCount
|
limit = s.config.RpcConfig.FriendSyncCount
|
||||||
@ -35,14 +39,15 @@ func (s *friendServer) IncrSyncFriends(ctx context.Context, req *pbfriend.IncrSy
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(sortUserIDs) == 0 {
|
if len(sortUserIDs) == 0 {
|
||||||
return &pbfriend.IncrSyncFriendsResp{
|
return &pbfriend.GetIncrementalFriendsResp{
|
||||||
Version: uint64(incrVer.Version),
|
Version: uint64(incrVer.Version),
|
||||||
|
VersionID: dataver.VersionIDStr(incrVer.ID),
|
||||||
Full: true,
|
Full: true,
|
||||||
SyncCount: uint32(s.config.RpcConfig.FriendSyncCount),
|
SyncCount: uint32(s.config.RpcConfig.FriendSyncCount),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
var changes []*relation.FriendModel
|
var changes []*relation.FriendModel
|
||||||
res := dataver.NewSyncResult(incrVer, sortUserIDs)
|
res := dataver.NewSyncResult(incrVer, sortUserIDs, req.VersionID)
|
||||||
if len(res.Changes) > 0 {
|
if len(res.Changes) > 0 {
|
||||||
changes, err = s.friendDatabase.FindFriendsWithError(ctx, req.UserID, res.Changes)
|
changes, err = s.friendDatabase.FindFriendsWithError(ctx, req.UserID, res.Changes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -53,8 +58,9 @@ func (s *friendServer) IncrSyncFriends(ctx context.Context, req *pbfriend.IncrSy
|
|||||||
if calcHash == req.IdHash {
|
if calcHash == req.IdHash {
|
||||||
sortUserIDs = nil
|
sortUserIDs = nil
|
||||||
}
|
}
|
||||||
return &pbfriend.IncrSyncFriendsResp{
|
return &pbfriend.GetIncrementalFriendsResp{
|
||||||
Version: uint64(res.Version),
|
Version: uint64(res.Version),
|
||||||
|
VersionID: res.VersionID,
|
||||||
Full: res.Full,
|
Full: res.Full,
|
||||||
SyncCount: uint32(s.config.RpcConfig.FriendSyncCount),
|
SyncCount: uint32(s.config.RpcConfig.FriendSyncCount),
|
||||||
SortUserIdHash: calcHash,
|
SortUserIdHash: calcHash,
|
||||||
|
|||||||
16
internal/rpc/group/sync.go
Normal file
16
internal/rpc/group/sync.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package group
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
pbgroup "github.com/openimsdk/protocol/group"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *groupServer) SearchGroupMember(ctx context.Context, req *pbgroup.SearchGroupMemberReq) (*pbgroup.SearchGroupMemberResp, error) {
|
||||||
|
//TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupServer) GetGroupMemberHash(ctx context.Context, req *pbgroup.GetGroupMemberHashReq) (*pbgroup.GetGroupMemberHashResp, error) {
|
||||||
|
//TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
@ -56,6 +56,11 @@ type userServer struct {
|
|||||||
webhookClient *webhook.Client
|
webhookClient *webhook.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *userServer) SearchUser(ctx context.Context, req *pbuser.SearchUserReq) (*pbuser.SearchUserResp, error) {
|
||||||
|
//TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
RpcConfig config.User
|
RpcConfig config.User
|
||||||
RedisConfig config.Redis
|
RedisConfig config.Redis
|
||||||
|
|||||||
@ -52,6 +52,27 @@ type Elem struct {
|
|||||||
LastUpdate time.Time `bson:"last_update"`
|
LastUpdate time.Time `bson:"last_update"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tableWriteLog struct {
|
||||||
|
ID primitive.ObjectID `bson:"_id"`
|
||||||
|
DID string `bson:"d_id"`
|
||||||
|
Logs []Elem `bson:"logs"`
|
||||||
|
Version uint `bson:"version"`
|
||||||
|
Deleted uint `bson:"deleted"`
|
||||||
|
LastUpdate time.Time `bson:"last_update"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tableWriteLog) WriteLog() *WriteLog {
|
||||||
|
return &WriteLog{
|
||||||
|
ID: t.ID,
|
||||||
|
DID: t.DID,
|
||||||
|
Logs: t.Logs,
|
||||||
|
Version: t.Version,
|
||||||
|
Deleted: t.Deleted,
|
||||||
|
LastUpdate: t.LastUpdate,
|
||||||
|
LogLen: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type DataLog interface {
|
type DataLog interface {
|
||||||
WriteLog(ctx context.Context, dId string, eIds []string, deleted bool) error
|
WriteLog(ctx context.Context, dId string, eIds []string, deleted bool) error
|
||||||
FindChangeLog(ctx context.Context, dId string, version uint, limit int) (*WriteLog, error)
|
FindChangeLog(ctx context.Context, dId string, version uint, limit int) (*WriteLog, error)
|
||||||
@ -94,7 +115,7 @@ func (l *logModel) WriteLog(ctx context.Context, dId string, eIds []string, dele
|
|||||||
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, deleted, now); err == nil {
|
||||||
return nil
|
return nil
|
||||||
} else if !mongo.IsDuplicateKeyError(err) {
|
} else if !mongo.IsDuplicateKeyError(err) {
|
||||||
return err
|
return err
|
||||||
@ -107,15 +128,9 @@ func (l *logModel) WriteLog(ctx context.Context, dId string, eIds []string, dele
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logModel) initDoc(ctx context.Context, dId string, eIds []string, deleted bool, now time.Time) error {
|
func (l *logModel) initDoc(ctx context.Context, dId string, eIds []string, deleted bool, now time.Time) (*tableWriteLog, error) {
|
||||||
type tableWriteLog struct {
|
|
||||||
DID string `bson:"d_id"`
|
|
||||||
Logs []Elem `bson:"logs"`
|
|
||||||
Version uint `bson:"version"`
|
|
||||||
Deleted uint `bson:"deleted"`
|
|
||||||
LastUpdate time.Time `bson:"last_update"`
|
|
||||||
}
|
|
||||||
wl := tableWriteLog{
|
wl := tableWriteLog{
|
||||||
|
ID: primitive.NewObjectID(),
|
||||||
DID: dId,
|
DID: dId,
|
||||||
Logs: make([]Elem, 0, len(eIds)),
|
Logs: make([]Elem, 0, len(eIds)),
|
||||||
Version: FirstVersion,
|
Version: FirstVersion,
|
||||||
@ -131,12 +146,12 @@ func (l *logModel) initDoc(ctx context.Context, dId string, eIds []string, delet
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
_, err := l.coll.InsertOne(ctx, &wl)
|
_, err := l.coll.InsertOne(ctx, &wl)
|
||||||
return err
|
return &wl, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logModel) writeLogBatch(ctx context.Context, dId string, eIds []string, deleted bool, now time.Time) (*mongo.UpdateResult, error) {
|
func (l *logModel) writeLogBatch(ctx context.Context, dId string, eIds []string, deleted bool, now time.Time) (*mongo.UpdateResult, error) {
|
||||||
if len(eIds) == 0 {
|
if eIds == nil {
|
||||||
return nil, errs.ErrArgs.WrapMsg("elem id is empty", "dId", dId)
|
eIds = []string{}
|
||||||
}
|
}
|
||||||
filter := bson.M{
|
filter := bson.M{
|
||||||
"d_id": dId,
|
"d_id": dId,
|
||||||
@ -195,17 +210,25 @@ func (l *logModel) writeLogBatch(ctx context.Context, dId string, eIds []string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *logModel) findDoc(ctx context.Context, dId string) (*WriteLog, error) {
|
func (l *logModel) findDoc(ctx context.Context, dId string) (*WriteLog, error) {
|
||||||
res, err := mongoutil.FindOne[*WriteLog](ctx, l.coll, bson.M{"d_id": dId}, options.FindOne().SetProjection(bson.M{"logs": 0}))
|
return mongoutil.FindOne[*WriteLog](ctx, l.coll, bson.M{"d_id": dId}, options.FindOne().SetProjection(bson.M{"logs": 0}))
|
||||||
if err == nil {
|
}
|
||||||
return res, nil
|
|
||||||
} else if errors.Is(err, mongo.ErrNoDocuments) {
|
func (l *logModel) FindChangeLog(ctx context.Context, dId string, version uint, limit int) (*WriteLog, error) {
|
||||||
return &WriteLog{}, nil
|
if wl, err := l.findChangeLog(ctx, dId, version, limit); err == nil {
|
||||||
|
return wl, nil
|
||||||
|
} else if !errors.Is(err, mongo.ErrNoDocuments) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if res, err := l.initDoc(ctx, dId, nil, false, time.Now()); err == nil {
|
||||||
|
return res.WriteLog(), nil
|
||||||
|
} else if mongo.IsDuplicateKeyError(err) {
|
||||||
|
return l.findChangeLog(ctx, dId, version, limit)
|
||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logModel) FindChangeLog(ctx context.Context, dId string, version uint, limit int) (*WriteLog, error) {
|
func (l *logModel) findChangeLog(ctx context.Context, dId string, version uint, limit int) (*WriteLog, error) {
|
||||||
if version == 0 && limit == 0 {
|
if version == 0 && limit == 0 {
|
||||||
return l.findDoc(ctx, dId)
|
return l.findDoc(ctx, dId)
|
||||||
}
|
}
|
||||||
@ -271,7 +294,7 @@ func (l *logModel) FindChangeLog(ctx context.Context, dId string, version uint,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(res) == 0 {
|
if len(res) == 0 {
|
||||||
return &WriteLog{}, nil
|
return nil, mongo.ErrNoDocuments
|
||||||
}
|
}
|
||||||
return res[0], nil
|
return res[0], nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,29 @@
|
|||||||
package dataver
|
package dataver
|
||||||
|
|
||||||
import "github.com/openimsdk/tools/utils/datautil"
|
import (
|
||||||
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
type SyncResult struct {
|
type SyncResult struct {
|
||||||
Version uint
|
Version uint
|
||||||
|
VersionID string
|
||||||
DeleteEID []string
|
DeleteEID []string
|
||||||
Changes []string
|
Changes []string
|
||||||
Full bool
|
Full bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncResult(wl *WriteLog, fullIDs []string) *SyncResult {
|
func VersionIDStr(id primitive.ObjectID) string {
|
||||||
|
if id.IsZero() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return id.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSyncResult(wl *WriteLog, fullIDs []string, versionID string) *SyncResult {
|
||||||
var findEIDs []string
|
var findEIDs []string
|
||||||
var res SyncResult
|
var res SyncResult
|
||||||
if wl.Full() {
|
if wl.Full() || VersionIDStr(wl.ID) != versionID {
|
||||||
res.Changes = fullIDs
|
res.Changes = fullIDs
|
||||||
res.Full = true
|
res.Full = true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -193,20 +193,6 @@ func (f *FriendMgo) FindIncrVersion(ctx context.Context, ownerUserID string, ver
|
|||||||
return f.owner.FindChangeLog(ctx, ownerUserID, version, limit)
|
return f.owner.FindChangeLog(ctx, ownerUserID, version, limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (f *FriendMgo) IncrSync(ctx context.Context, ownerUserID string, version uint, limit int) (*dataver.SyncResult[*relation.FriendModel], error) {
|
|
||||||
// res, err := f.owner.FindChangeLog(ctx, ownerUserID, version, limit)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// return dataver.NewSyncResult[*relation.FriendModel](res, func(eIds []string) ([]*relation.FriendModel, error) {
|
|
||||||
// if len(eIds) == 0 {
|
|
||||||
// return nil, errors.New("todo")
|
|
||||||
// } else {
|
|
||||||
// return f.FindFriends(ctx, ownerUserID, eIds)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
//}
|
|
||||||
|
|
||||||
func IncrVersion(dbs ...func() error) error {
|
func IncrVersion(dbs ...func() error) error {
|
||||||
for _, fn := range dbs {
|
for _, fn := range dbs {
|
||||||
if err := fn(); err != nil {
|
if err := fn(); err != nil {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user