You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.0 KiB
167 lines
4.0 KiB
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 |
|
}
|
|
|