package richtextser import ( "context" "strings" "sync" "videoweb/app/api/proto" "videoweb/pub/common/log" "videoweb/pub/common/srvdef" "videoweb/pub/models/richtextcontentmod" "github.com/robfig/cron/v3" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) var ( richTextCron *cron.Cron richTextCache = struct { sync.RWMutex byTitle map[string]proto.RichTextInfo }{ byTitle: make(map[string]proto.RichTextInfo), } ) // Start 启动富文本缓存,每10分钟刷新一次。 func Start() { richTextCron = cron.New(cron.WithSeconds()) UpdateCache(context.Background()) _, _ = richTextCron.AddFunc("0 */10 * * * ?", func() { UpdateCache(context.Background()) }) richTextCron.Start() } // Stop 停止富文本缓存刷新任务。 func Stop() { if richTextCron != nil { richTextCron.Stop() } } // UpdateCache 更新全部启用的富文本;查询失败时保留原缓存。 func UpdateCache(ctx context.Context) { list, serr := richtextcontentmod.FindManyRichTextContentModelModel(ctx, bson.M{richtextcontentmod.FN.RichTextContentModel.Status: true}, options.Find().SetSort(bson.D{{Key: richtextcontentmod.FN.RichTextContentModel.UpdatedAt, Value: 1}})) if serr != nil { log.Warn("richtextser.UpdateCache failed, keep old cache", log.E(serr)) return } next := make(map[string]proto.RichTextInfo, len(list)) for _, item := range list { if item == nil { continue } title := strings.TrimSpace(item.Title) if title == "" { continue } next[title] = proto.RichTextInfo{ Id: item.Id, Title: item.Title, Content: item.Content, Desc: item.Desc, SeoInfo: item.SeoInfo, } } richTextCache.Lock() richTextCache.byTitle = next richTextCache.Unlock() } // GetByTitle 从缓存按 title 获取富文本。 func GetByTitle(title string) (proto.RichTextInfo, *srvdef.SrvErr) { title = strings.TrimSpace(title) if title == "" { return proto.RichTextInfo{}, srvdef.New(srvdef.ErrParamError, "", "") } richTextCache.RLock() data, ok := richTextCache.byTitle[title] richTextCache.RUnlock() if !ok { return proto.RichTextInfo{}, srvdef.New(srvdef.ErrNoData, "", "") } return data, nil }