168 lines
4.0 KiB
Go
168 lines
4.0 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"sync"
|
||
|
|
||
|
tagmdl "go-common/app/interface/main/tag/model"
|
||
|
"go-common/app/interface/main/web/model"
|
||
|
arcmdl "go-common/app/service/main/archive/api"
|
||
|
"go-common/library/log"
|
||
|
"go-common/library/net/metadata"
|
||
|
"go-common/library/sync/errgroup"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
_tagBlkSize = 50
|
||
|
_tagArcType = 3
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
_emptyWxArc = make([]*model.WxArchive, 0)
|
||
|
_emptyWxArcTag = make([]*model.WxArcTag, 0)
|
||
|
)
|
||
|
|
||
|
// WxHot get wx hot archives.
|
||
|
func (s *Service) WxHot(c context.Context, pn, ps int) (res []*model.WxArchive, count int, err error) {
|
||
|
var (
|
||
|
addCache = true
|
||
|
aids []int64
|
||
|
wxArcs, allRes []*model.WxArchive
|
||
|
arcs map[int64]*model.WxArchive
|
||
|
)
|
||
|
defer func() {
|
||
|
res, count = wxHotPage(allRes, pn, ps)
|
||
|
}()
|
||
|
if wxArcs, err = s.dao.WxHotCache(c); err != nil {
|
||
|
err = nil
|
||
|
addCache = false
|
||
|
} else if len(wxArcs) > 0 {
|
||
|
allRes = s.fmtWxArcs(c, wxArcs)
|
||
|
return
|
||
|
}
|
||
|
if aids, err = s.dao.WxHot(c); err != nil {
|
||
|
err = nil
|
||
|
} else if len(aids) > s.c.Rule.MinWxHotCount {
|
||
|
if arcs, err = s.archiveWithTag(c, aids); err != nil {
|
||
|
err = nil
|
||
|
} else if len(arcs) > 0 {
|
||
|
for _, aid := range aids {
|
||
|
if arc, ok := arcs[aid]; ok && arc != nil {
|
||
|
allRes = append(allRes, arc)
|
||
|
}
|
||
|
}
|
||
|
if addCache {
|
||
|
s.cache.Do(c, func(c context.Context) {
|
||
|
s.dao.SetWxHotCache(c, allRes)
|
||
|
})
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
} else {
|
||
|
log.Error("s.dao.WxHot len(%d)", len(allRes))
|
||
|
}
|
||
|
allRes, err = s.dao.WxHotBakCache(c)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func wxHotPage(list []*model.WxArchive, pn, ps int) (res []*model.WxArchive, count int) {
|
||
|
count = len(list)
|
||
|
start := (pn - 1) * ps
|
||
|
end := start + ps - 1
|
||
|
if count == 0 || count < start {
|
||
|
res = _emptyWxArc
|
||
|
return
|
||
|
}
|
||
|
if count > end {
|
||
|
res = list[start : end+1]
|
||
|
} else {
|
||
|
res = list[start:]
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) archiveWithTag(c context.Context, aids []int64) (list map[int64]*model.WxArchive, err error) {
|
||
|
var (
|
||
|
arcErr, tagErr error
|
||
|
arcsReply *arcmdl.ArcsReply
|
||
|
tags map[int64][]*tagmdl.Tag
|
||
|
mutex = sync.Mutex{}
|
||
|
ip = metadata.String(c, metadata.RemoteIP)
|
||
|
)
|
||
|
group, errCtx := errgroup.WithContext(c)
|
||
|
group.Go(func() error {
|
||
|
if arcsReply, arcErr = s.arcClient.Arcs(errCtx, &arcmdl.ArcsRequest{Aids: aids}); arcErr != nil {
|
||
|
log.Error("s.arcClient.Arcs(%d) error %v", aids, err)
|
||
|
return arcErr
|
||
|
}
|
||
|
return nil
|
||
|
})
|
||
|
aidsLen := len(aids)
|
||
|
tags = make(map[int64][]*tagmdl.Tag, aidsLen)
|
||
|
for i := 0; i < aidsLen; i += _tagBlkSize {
|
||
|
var partAids []int64
|
||
|
if i+_tagBlkSize > aidsLen {
|
||
|
partAids = aids[i:]
|
||
|
} else {
|
||
|
partAids = aids[i : i+_tagBlkSize]
|
||
|
}
|
||
|
group.Go(func() (err error) {
|
||
|
var tmpRes map[int64][]*tagmdl.Tag
|
||
|
arg := &tagmdl.ArgResTags{Oids: partAids, Type: _tagArcType, RealIP: ip}
|
||
|
if tmpRes, tagErr = s.tag.ResTags(errCtx, arg); tagErr != nil {
|
||
|
log.Error("s.tag.ResTag(%+v) error(%v)", arg, tagErr)
|
||
|
return
|
||
|
}
|
||
|
mutex.Lock()
|
||
|
for aid, tmpTags := range tmpRes {
|
||
|
tags[aid] = tmpTags
|
||
|
}
|
||
|
mutex.Unlock()
|
||
|
return nil
|
||
|
})
|
||
|
}
|
||
|
if err = group.Wait(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
list = make(map[int64]*model.WxArchive, len(aids))
|
||
|
for _, aid := range aids {
|
||
|
if arc, ok := arcsReply.Arcs[aid]; ok && arc.IsNormal() {
|
||
|
wxArc := new(model.WxArchive)
|
||
|
wxArc.FromArchive(arc)
|
||
|
if tag, ok := tags[aid]; ok {
|
||
|
for _, v := range tag {
|
||
|
wxArc.Tags = append(wxArc.Tags, &model.WxArcTag{ID: v.ID, Name: v.Name})
|
||
|
}
|
||
|
}
|
||
|
if len(wxArc.Tags) == 0 {
|
||
|
wxArc.Tags = _emptyWxArcTag
|
||
|
}
|
||
|
list[aid] = wxArc
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) fmtWxArcs(c context.Context, arcs []*model.WxArchive) (res []*model.WxArchive) {
|
||
|
var (
|
||
|
aids []int64
|
||
|
newArcs map[int64]*model.WxArchive
|
||
|
err error
|
||
|
)
|
||
|
for _, arc := range arcs {
|
||
|
aids = append(aids, arc.Aid)
|
||
|
}
|
||
|
if newArcs, err = s.archiveWithTag(c, aids); err != nil {
|
||
|
log.Error("fmtWxArcStat archiveWithTag aids(%+v) error(%v)", aids, err)
|
||
|
return
|
||
|
}
|
||
|
for _, arc := range arcs {
|
||
|
if newArc, ok := newArcs[arc.Aid]; ok {
|
||
|
res = append(res, newArc)
|
||
|
} else {
|
||
|
res = append(res, arc)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|