mirror of
				https://github.com/openimsdk/open-im-server.git
				synced 2025-10-31 16:32:12 +08:00 
			
		
		
		
	* fix: GroupApplicationAcceptedNotification * fix: GroupApplicationAcceptedNotification * fix: NotificationUserInfoUpdate * cicd: robot automated Change * fix: component * fix: getConversationInfo * feat: cron task * feat: cron task * feat: cron task * feat: cron task * feat: cron task * fix: minio config url recognition error * new mongo * new mongo * new mongo * new mongo * new mongo * new mongo * new mongo * new mongo * friend incr sync * friend incr sync * friend incr sync * friend incr sync * friend incr sync * mage * optimization version log * optimization version log * sync * sync * sync * group sync * sync option * sync option * refactor: replace `friend` package with `realtion`. * refactor: update lastest commit to relation. * sync option * sync option * sync option * sync * sync * go.mod * update: go mod * refactor: change incremental to full * feat: get full friend user ids * feat: api and config * group version * merge * fix: sort by id avoid unstable sort friends. * group * group * group * fix: sort by id avoid unstable sort friends. * fix: sort by id avoid unstable sort friends. * fix: sort by id avoid unstable sort friends. * user version * fix: sort by id avoid unstable sort friends. * test: test log add. * test: debug log remove. * fix: transfer group owner incr version more than 1. * fix: add condition to kick owner. * feat: replace resp nil * feat: replace nil * fix: delete cache of max group joined version avoid sync joined group failed. * fix: nil * fix: delete cache of max group joined version avoid sync joined group failed. * fix: delete cache of max group joined version avoid sync joined group failed. * return group information for any changes * online cache --------- Co-authored-by: withchao <withchao@users.noreply.github.com> Co-authored-by: Monet Lee <monet_lee@163.com> Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com> Co-authored-by: icey-yu <1186114839@qq.com>
		
			
				
	
	
		
			157 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package incrversion
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
 | |
| 	"github.com/openimsdk/tools/errs"
 | |
| 	"go.mongodb.org/mongo-driver/bson/primitive"
 | |
| )
 | |
| 
 | |
| //func Limit(maxSync int, version uint64) int {
 | |
| //	if version == 0 {
 | |
| //		return 0
 | |
| //	}
 | |
| //	return maxSync
 | |
| //}
 | |
| 
 | |
| const syncLimit = 200
 | |
| 
 | |
| const (
 | |
| 	tagQuery = iota + 1
 | |
| 	tagFull
 | |
| 	tageEqual
 | |
| )
 | |
| 
 | |
| type Option[A, B any] struct {
 | |
| 	Ctx           context.Context
 | |
| 	VersionKey    string
 | |
| 	VersionID     string
 | |
| 	VersionNumber uint64
 | |
| 	//SyncLimit       int
 | |
| 	CacheMaxVersion func(ctx context.Context, dId string) (*model.VersionLog, error)
 | |
| 	Version         func(ctx context.Context, dId string, version uint, limit int) (*model.VersionLog, error)
 | |
| 	//SortID          func(ctx context.Context, dId string) ([]string, error)
 | |
| 	Find func(ctx context.Context, ids []string) ([]A, error)
 | |
| 	ID   func(elem A) string
 | |
| 	Resp func(version *model.VersionLog, deleteIds []string, insertList, updateList []A, full bool) *B
 | |
| }
 | |
| 
 | |
| func (o *Option[A, B]) newError(msg string) error {
 | |
| 	return errs.ErrInternalServer.WrapMsg(msg)
 | |
| }
 | |
| 
 | |
| func (o *Option[A, B]) check() error {
 | |
| 	if o.Ctx == nil {
 | |
| 		return o.newError("opt ctx is nil")
 | |
| 	}
 | |
| 	if o.VersionKey == "" {
 | |
| 		return o.newError("versionKey is empty")
 | |
| 	}
 | |
| 	//if o.SyncLimit <= 0 {
 | |
| 	//	return o.newError("invalid synchronization quantity")
 | |
| 	//}
 | |
| 	if o.Version == nil {
 | |
| 		return o.newError("func version is nil")
 | |
| 	}
 | |
| 	//if o.SortID == nil {
 | |
| 	//	return o.newError("func allID is nil")
 | |
| 	//}
 | |
| 	if o.Find == nil {
 | |
| 		return o.newError("func find is nil")
 | |
| 	}
 | |
| 	if o.ID == nil {
 | |
| 		return o.newError("func id is nil")
 | |
| 	}
 | |
| 	if o.Resp == nil {
 | |
| 		return o.newError("func resp is nil")
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (o *Option[A, B]) validVersion() bool {
 | |
| 	objID, err := primitive.ObjectIDFromHex(o.VersionID)
 | |
| 	return err == nil && (!objID.IsZero()) && o.VersionNumber > 0
 | |
| }
 | |
| 
 | |
| func (o *Option[A, B]) equalID(objID primitive.ObjectID) bool {
 | |
| 	return o.VersionID == objID.Hex()
 | |
| }
 | |
| 
 | |
| func (o *Option[A, B]) getVersion(tag *int) (*model.VersionLog, error) {
 | |
| 	if o.CacheMaxVersion == nil {
 | |
| 		if o.validVersion() {
 | |
| 			*tag = tagQuery
 | |
| 			return o.Version(o.Ctx, o.VersionKey, uint(o.VersionNumber), syncLimit)
 | |
| 		}
 | |
| 		*tag = tagFull
 | |
| 		return o.Version(o.Ctx, o.VersionKey, 0, 0)
 | |
| 	} else {
 | |
| 		cache, err := o.CacheMaxVersion(o.Ctx, o.VersionKey)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if !o.validVersion() {
 | |
| 			*tag = tagFull
 | |
| 			return cache, nil
 | |
| 		}
 | |
| 		if !o.equalID(cache.ID) {
 | |
| 			*tag = tagFull
 | |
| 			return cache, nil
 | |
| 		}
 | |
| 		if o.VersionNumber == uint64(cache.Version) {
 | |
| 			*tag = tageEqual
 | |
| 			return cache, nil
 | |
| 		}
 | |
| 		*tag = tagQuery
 | |
| 		return o.Version(o.Ctx, o.VersionKey, uint(o.VersionNumber), syncLimit)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o *Option[A, B]) Build() (*B, error) {
 | |
| 	if err := o.check(); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	var tag int
 | |
| 	version, err := o.getVersion(&tag)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	var full bool
 | |
| 	switch tag {
 | |
| 	case tagQuery:
 | |
| 		full = version.ID.Hex() != o.VersionID || uint64(version.Version) < o.VersionNumber || len(version.Logs) != version.LogLen
 | |
| 	case tagFull:
 | |
| 		full = true
 | |
| 	case tageEqual:
 | |
| 		full = false
 | |
| 	default:
 | |
| 		panic(fmt.Errorf("undefined tag %d", tag))
 | |
| 	}
 | |
| 	var (
 | |
| 		insertIds []string
 | |
| 		deleteIds []string
 | |
| 		updateIds []string
 | |
| 	)
 | |
| 	if !full {
 | |
| 		insertIds, deleteIds, updateIds = version.DeleteAndChangeIDs()
 | |
| 	}
 | |
| 	var (
 | |
| 		insertList []A
 | |
| 		updateList []A
 | |
| 	)
 | |
| 	if len(insertIds) > 0 {
 | |
| 		insertList, err = o.Find(o.Ctx, insertIds)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 	if len(updateIds) > 0 {
 | |
| 		updateList, err = o.Find(o.Ctx, updateIds)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 	return o.Resp(version, deleteIds, insertList, updateList, full), nil
 | |
| }
 |