mirror of
				https://github.com/openimsdk/open-im-server.git
				synced 2025-11-04 19:32:17 +08:00 
			
		
		
		
	seq
This commit is contained in:
		
							parent
							
								
									a2a28b43c5
								
							
						
					
					
						commit
						cce382d0c3
					
				@ -15,15 +15,9 @@ func Result[V any](val V, err error) V {
 | 
			
		||||
	return val
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Check(err error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestName(t *testing.T) {
 | 
			
		||||
	cli := Result(mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.48:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second)))
 | 
			
		||||
	tmp, err := NewSeqMongo(cli.Database("openim_v3"))
 | 
			
		||||
	tmp, err := NewSeqConversationMongo(cli.Database("openim_v3"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -14,4 +14,5 @@ serviceBinaries:
 | 
			
		||||
toolBinaries:
 | 
			
		||||
  - check-free-memory
 | 
			
		||||
  - check-component
 | 
			
		||||
  - seq
 | 
			
		||||
maxFileDescriptors: 10000
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,11 @@ import (
 | 
			
		||||
	"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
 | 
			
		||||
	"github.com/openimsdk/tools/db/mongoutil"
 | 
			
		||||
	"github.com/openimsdk/tools/db/redisutil"
 | 
			
		||||
	"github.com/openimsdk/tools/utils/datautil"
 | 
			
		||||
	"github.com/redis/go-redis/v9"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/mongo"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
			
		||||
	"gopkg.in/yaml.v3"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
@ -23,7 +25,12 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const batchSize = 5
 | 
			
		||||
const (
 | 
			
		||||
	batchSize             = 100
 | 
			
		||||
	dataVersionCollection = "data_version"
 | 
			
		||||
	seqKey                = "seq"
 | 
			
		||||
	seqVersion            = 38
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func readConfig[T any](dir string, name string) (*T, error) {
 | 
			
		||||
	data, err := os.ReadFile(filepath.Join(dir, name))
 | 
			
		||||
@ -37,7 +44,7 @@ func readConfig[T any](dir string, name string) (*T, error) {
 | 
			
		||||
	return &conf, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func redisKey(rdb redis.UniversalClient, prefix string, fn func(ctx context.Context, key string, delKey map[string]struct{}) error) error {
 | 
			
		||||
func redisKey(rdb redis.UniversalClient, prefix string, del time.Duration, fn func(ctx context.Context, key string, delKey map[string]struct{}) error) error {
 | 
			
		||||
	var (
 | 
			
		||||
		cursor uint64
 | 
			
		||||
		keys   []string
 | 
			
		||||
@ -58,9 +65,20 @@ func redisKey(rdb redis.UniversalClient, prefix string, fn func(ctx context.Cont
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(delKey) > 0 {
 | 
			
		||||
			//if err := rdb.Del(ctx, datautil.Keys(delKey)...).Err(); err != nil {
 | 
			
		||||
			//	return err
 | 
			
		||||
			//}
 | 
			
		||||
			delKeys := datautil.Keys(delKey)
 | 
			
		||||
			if del < time.Second {
 | 
			
		||||
				if err := rdb.Del(ctx, datautil.Keys(delKey)...).Err(); err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				pipe := rdb.Pipeline()
 | 
			
		||||
				for _, key := range delKeys {
 | 
			
		||||
					pipe.Expire(ctx, key, del)
 | 
			
		||||
				}
 | 
			
		||||
				if _, err := pipe.Exec(ctx); err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if cursor == 0 {
 | 
			
		||||
			return nil
 | 
			
		||||
@ -68,7 +86,7 @@ func redisKey(rdb redis.UniversalClient, prefix string, fn func(ctx context.Cont
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Main(conf string) error {
 | 
			
		||||
func Main(conf string, del time.Duration) error {
 | 
			
		||||
	redisConfig, err := readConfig[config.Redis](conf, cmd.RedisConfigFileName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@ -87,12 +105,22 @@ func Main(conf string) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	versionColl := mgocli.GetDB().Collection(dataVersionCollection)
 | 
			
		||||
	converted, err := CheckVersion(versionColl, seqKey, seqVersion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if converted {
 | 
			
		||||
		fmt.Println("[seq] seq data has been converted")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := mgo.NewSeqConversationMongo(mgocli.GetDB()); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	coll := mgocli.GetDB().Collection(database.SeqConversationName)
 | 
			
		||||
	const prefix = cachekey.MaxSeq
 | 
			
		||||
	return redisKey(rdb, prefix, func(ctx context.Context, key string, delKey map[string]struct{}) error {
 | 
			
		||||
	fmt.Println("start to convert seq conversation")
 | 
			
		||||
	err = redisKey(rdb, prefix, del, func(ctx context.Context, key string, delKey map[string]struct{}) error {
 | 
			
		||||
		conversationId := strings.TrimPrefix(key, prefix)
 | 
			
		||||
		delKey[key] = struct{}{}
 | 
			
		||||
		maxValue, err := rdb.Get(ctx, key).Result()
 | 
			
		||||
@ -149,4 +177,42 @@ func Main(conf string) error {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println("convert seq conversation success")
 | 
			
		||||
	return SetVersion(versionColl, seqKey, seqVersion)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CheckVersion(coll *mongo.Collection, key string, currentVersion int) (converted bool, err error) {
 | 
			
		||||
	type VersionTable struct {
 | 
			
		||||
		Key   string `bson:"key"`
 | 
			
		||||
		Value string `bson:"value"`
 | 
			
		||||
	}
 | 
			
		||||
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
 | 
			
		||||
	defer cancel()
 | 
			
		||||
	res, err := mongoutil.FindOne[VersionTable](ctx, coll, bson.M{"key": key})
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		ver, err := strconv.Atoi(res.Value)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return false, fmt.Errorf("version %s parse error %w", res.Value, err)
 | 
			
		||||
		}
 | 
			
		||||
		if ver >= currentVersion {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
		return false, nil
 | 
			
		||||
	} else if errors.Is(err, mongo.ErrNoDocuments) {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	} else {
 | 
			
		||||
		return false, err
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetVersion(coll *mongo.Collection, key string, version int) error {
 | 
			
		||||
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
 | 
			
		||||
	defer cancel()
 | 
			
		||||
	option := options.Update().SetUpsert(true)
 | 
			
		||||
	filter := bson.M{"key": key, "value": strconv.Itoa(version)}
 | 
			
		||||
	update := bson.M{"$set": bson.M{"key": key, "value": strconv.Itoa(version)}}
 | 
			
		||||
	return mongoutil.UpdateOne(ctx, coll, filter, update, false, option)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,18 @@ import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/openimsdk/open-im-server/v3/tools/seq/internal"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var config string
 | 
			
		||||
	flag.StringVar(&config, "redis", "/Users/chao/Desktop/project/open-im-server/config", "config directory")
 | 
			
		||||
	var (
 | 
			
		||||
		config string
 | 
			
		||||
		second int
 | 
			
		||||
	)
 | 
			
		||||
	flag.StringVar(&config, "c", "", "config directory")
 | 
			
		||||
	flag.IntVar(&second, "sec", 3600*24, "delayed deletion of the original seq key after conversion")
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
	if err := internal.Main(config); err != nil {
 | 
			
		||||
	if err := internal.Main(config, time.Duration(second)*time.Second); err != nil {
 | 
			
		||||
		fmt.Println("seq task", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user