package service import ( "sync" "time" "91porn-server/common" "91porn-server/common/log" "91porn-server/common/stderr" "91porn-server/models/v/chatrobotmod" "91porn-server/models/v/vidmod" "github.com/robfig/cron/v3" "go.mongodb.org/mongo-driver/bson" ) const SingleQueryLimit = 5000 var VideoInfo *VideoInfoFaker type VideoInfoFaker struct { once sync.Once limit int64 // 限制每次查询的数据量 mu *sync.Mutex } func newVideoInfoFaker() *VideoInfoFaker { return &VideoInfoFaker{ once: sync.Once{}, limit: SingleQueryLimit, mu: &sync.Mutex{}, } } // FullUpdate 单次更新,程序启动后执行一次 func (f *VideoInfoFaker) FullUpdate() { f.once.Do( func() { f.mu.Lock() log.Debug("full update start...") common.Go(func() { defer f.mu.Unlock() start := time.Now() totalUpdate, err := f.fakeVideoInfo() log.Info("FullUpdate fihish", log.Any("time(s)", time.Since(start).Seconds()), log.Any("total", totalUpdate), log.E(err)) }) }, ) } // CronUpdate 定时更新 func (f *VideoInfoFaker) CronUpdate() { f.mu.Lock() defer f.mu.Unlock() start := time.Now() totalUpdate, err := f.fakeVideoInfo() log.Info("CronUpdate fihish", log.Any("time(s)", time.Since(start).Seconds()), log.Any("total", totalUpdate), log.E(err)) } func (f *VideoInfoFaker) RegisterCronJob(cron *cron.Cron) { f.mu.Lock() defer f.mu.Unlock() _, _ = cron.AddFunc("0 0 10 */1 * *", f.CronUpdate) // 每隔三天,早上10点,仅在周一到周六执行 } // FakeVideoInfo 更新视频相关数据 func (f *VideoInfoFaker) fakeVideoInfo() (int64, error) { robotConf, err := chatrobotmod.GetRobotConfByType(chatrobotmod.Comment) if err != nil || robotConf.ID.IsZero() { return 0, err } if (robotConf.MaxFakeLikes <= 0 && robotConf.MaxFakePlayCount <= 0) || (robotConf.MinFakeLikes >= robotConf.MaxFakeLikes && robotConf.MinFakePlayCount >= robotConf.MaxFakePlayCount) { return 0, stderr.RobotInvalidConf } ticker := time.NewTicker(time.Second) defer ticker.Stop() pageSize, page, totalUpdate := f.limit, int64(0), int64(0) for pageSize == f.limit { videoList, err := vidmod.GetVideoListLtMinPlayLikeCount(int64(robotConf.MinFakeLikes), int64(robotConf.MinFakePlayCount), page*pageSize, pageSize) if err != nil { return totalUpdate, err } cnt := int64(0) for _, video := range videoList { set := bson.M{} if video.FakeLikeCount < robotConf.MinFakeLikes { destLike := common.RandInt(robotConf.MinFakeLikes, robotConf.MaxFakeLikes) set["fakeLikeCount"] = destLike } if video.FakePlayCount < robotConf.MinFakePlayCount { destPlay := common.RandInt(robotConf.MinFakePlayCount, robotConf.MaxFakePlayCount) video.FakePlayCount = destPlay set["fakePlayCount"] = destPlay } if set["fakePlayCount"] != 0 || set["fakeLikeCount"] != 0 { // log.Info("update", log.Any("set", set), log.Any("vid", video.ID), log.Any("origin like", video.FakeLikeCount), log.Any("origin play", video.PlayCount)) res, err := vidmod.UpdateOneByID(video.ID, set) if err != nil { // 遇到错误继续执行 log.Error("fakeVideoInfo UpdateOneByID", log.Any("videoID", video.ID), log.E(err)) } else { cnt += res.ModifiedCount } } } page++ pageSize = int64(len(videoList)) totalUpdate += cnt log.Info("fake progress", log.Any("page", page), log.Any("total", totalUpdate)) <-ticker.C } return totalUpdate, nil }