162 lines
4.2 KiB
Go
162 lines
4.2 KiB
Go
// Package seopush 为搜索引擎推送做兜底:补推已上架短剧,并重试失败的任务。
|
|
package seopush
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
"videoweb/pub/common/log"
|
|
"videoweb/pub/models/playletmod"
|
|
"videoweb/pub/models/seopushmod"
|
|
"videoweb/pub/pubdef"
|
|
"videoweb/web/service/srv_seopush"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
const (
|
|
backfillLimit = 100
|
|
retryLimit = 50
|
|
taskKeepDays = 30
|
|
)
|
|
|
|
var jobMu sync.Mutex
|
|
|
|
// Run 定时兜底任务
|
|
func Run() {
|
|
if !jobMu.TryLock() {
|
|
log.Warn("seopush: skip job, previous run still in progress")
|
|
return
|
|
}
|
|
defer jobMu.Unlock()
|
|
|
|
ctx := context.Background()
|
|
if !pubdef.Enabled() {
|
|
discardPendingTasks(ctx)
|
|
return
|
|
}
|
|
webAddr := srv_seopush.SEOBaseURL(ctx)
|
|
if webAddr == "" {
|
|
return
|
|
}
|
|
backfillVisiblePlaylets(ctx)
|
|
retryPendingTasks(ctx, webAddr)
|
|
cleanupExpiredTasks(ctx)
|
|
}
|
|
|
|
func discardPendingTasks(ctx context.Context) {
|
|
filter := bson.M{"$or": []bson.M{
|
|
{seopushmod.FN.SeoPushTask.GoogleStatus: seopushmod.PushStatusPending},
|
|
{seopushmod.FN.SeoPushTask.IndexNowStatus: seopushmod.PushStatusPending},
|
|
}}
|
|
list, serr := seopushmod.FindManySeoPushTasks(ctx, filter)
|
|
if serr != nil {
|
|
log.Warn("seopush: find pending tasks to discard failed", log.E(serr))
|
|
return
|
|
}
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
ids := make([]int64, 0, len(list))
|
|
seen := make(map[int64]struct{}, len(list))
|
|
for _, task := range list {
|
|
if task == nil || task.VideoId <= 0 {
|
|
continue
|
|
}
|
|
if _, ok := seen[task.VideoId]; ok {
|
|
continue
|
|
}
|
|
seen[task.VideoId] = struct{}{}
|
|
ids = append(ids, task.VideoId)
|
|
}
|
|
count, serr := seopushmod.DelManySeoPushTask(ctx, filter)
|
|
if serr != nil {
|
|
log.Warn("seopush: discard pending tasks failed", log.E(serr))
|
|
return
|
|
}
|
|
if len(ids) > 0 {
|
|
if serr := playletmod.UpdateManyPlaylet(ctx,
|
|
bson.M{playletmod.FN.Playlet.Id: bson.M{"$in": ids}},
|
|
bson.M{"$set": bson.M{playletmod.FN.Playlet.IndexNow: int64(0)}}); serr != nil {
|
|
log.Warn("seopush: reset playlet indexNow failed", log.E(serr))
|
|
}
|
|
}
|
|
log.Info("seopush=skip=disabled", log.Any("discarded", count))
|
|
}
|
|
|
|
func backfillVisiblePlaylets(ctx context.Context) {
|
|
filter := bson.M{
|
|
playletmod.FN.Playlet.Status: playletmod.StatusUp,
|
|
"$or": []bson.M{
|
|
{playletmod.FN.Playlet.IndexNow: 0},
|
|
{playletmod.FN.Playlet.IndexNow: bson.M{"$exists": false}},
|
|
},
|
|
}
|
|
opt := options.Find().
|
|
SetSort(bson.M{playletmod.FN.Playlet.OnlineAt: -1}).
|
|
SetLimit(backfillLimit)
|
|
|
|
list, serr := playletmod.FindManyPlaylet(ctx, filter, opt)
|
|
if serr != nil {
|
|
log.Warn("seopush: backfill find playlets failed", log.E(serr))
|
|
return
|
|
}
|
|
if len(list) == 0 {
|
|
return
|
|
}
|
|
for _, item := range list {
|
|
if item == nil {
|
|
continue
|
|
}
|
|
srv_seopush.RegisterPlayletUpdated(ctx, item.Id, item.Status, item.OnlineAt)
|
|
}
|
|
log.Info("seopush: backfill registered", log.Any("count", len(list)))
|
|
}
|
|
|
|
func retryPendingTasks(ctx context.Context, webAddr string) {
|
|
conds := []bson.M{
|
|
{
|
|
seopushmod.FN.SeoPushTask.GoogleStatus: seopushmod.PushStatusPending,
|
|
seopushmod.FN.SeoPushTask.GoogleRetry: bson.M{"$lt": seopushmod.MaxPushRetry},
|
|
},
|
|
{
|
|
seopushmod.FN.SeoPushTask.IndexNowStatus: seopushmod.PushStatusPending,
|
|
seopushmod.FN.SeoPushTask.IndexNowRetry: bson.M{"$lt": seopushmod.MaxPushRetry},
|
|
},
|
|
}
|
|
opt := options.Find().
|
|
SetSort(bson.M{seopushmod.FN.SeoPushTask.CreatedAt: 1}).
|
|
SetLimit(retryLimit)
|
|
taskList, serr := seopushmod.FindManySeoPushTasks(ctx, bson.M{"$or": conds}, opt)
|
|
if serr != nil {
|
|
log.Warn("seopush: find pending tasks failed", log.E(serr))
|
|
return
|
|
}
|
|
if len(taskList) == 0 {
|
|
return
|
|
}
|
|
for _, task := range taskList {
|
|
if task == nil || strings.Contains(task.Url, "?") {
|
|
continue
|
|
}
|
|
srv_seopush.PushTask(ctx, webAddr, task)
|
|
}
|
|
log.Info("seopush: pending tasks processed", log.Any("count", len(taskList)))
|
|
}
|
|
|
|
func cleanupExpiredTasks(ctx context.Context) {
|
|
deadline := time.Now().AddDate(0, 0, -taskKeepDays)
|
|
count, serr := seopushmod.DelManySeoPushTask(ctx, bson.M{
|
|
seopushmod.FN.SeoPushTask.UpdatedAt: bson.M{"$lt": deadline},
|
|
})
|
|
if serr != nil {
|
|
log.Warn("seopush: cleanup expired tasks failed", log.E(serr))
|
|
return
|
|
}
|
|
if count > 0 {
|
|
log.Info("seopush: expired tasks cleaned", log.Any("count", count))
|
|
}
|
|
}
|