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.
336 lines
8.6 KiB
336 lines
8.6 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"runtime" |
|
"strconv" |
|
"time" |
|
|
|
"go-common/app/interface/main/reply/conf" |
|
"go-common/app/interface/main/reply/dao/bigdata" |
|
"go-common/app/interface/main/reply/dao/drawyoo" |
|
"go-common/app/interface/main/reply/dao/fans" |
|
"go-common/app/interface/main/reply/dao/reply" |
|
"go-common/app/interface/main/reply/dao/search" |
|
"go-common/app/interface/main/reply/dao/vip" |
|
"go-common/app/interface/main/reply/dao/workflow" |
|
model "go-common/app/interface/main/reply/model/reply" |
|
artrpc "go-common/app/interface/openplatform/article/rpc/client" |
|
accrpc "go-common/app/service/main/account/api" |
|
arcrpc "go-common/app/service/main/archive/api/gorpc" |
|
assrpc "go-common/app/service/main/assist/rpc/client" |
|
figrpc "go-common/app/service/main/figure/rpc/client" |
|
filgrpc "go-common/app/service/main/filter/api/grpc/v1" |
|
replyfeed "go-common/app/service/main/reply-feed/api" |
|
|
|
locrpc "go-common/app/service/main/location/rpc/client" |
|
seqmdl "go-common/app/service/main/seq-server/model" |
|
seqrpc "go-common/app/service/main/seq-server/rpc/client" |
|
thumbup "go-common/app/service/main/thumbup/rpc/client" |
|
ugcpay "go-common/app/service/main/ugcpay/api/grpc/v1" |
|
"go-common/library/log" |
|
"go-common/library/log/infoc" |
|
"go-common/library/sync/pipeline/fanout" |
|
) |
|
|
|
var _defMemberJSON = []byte(`{"mid":"0","uname":"","sex":"保密","sign":"没签名","avatar":"http://static.hdslb.com/images/member/noface.gif","rank":"10000","DisplayRank":"0","level_info":{"current_level":0,"current_min":0,"current_exp":0,"next_exp":0},"pendant":{"pid":0,"name":"","image":"","expire":0},"nameplate":{"nid":0,"name":"","image":"","image_small":"","level":"","condition":""},"official_verify":{"type":-1,"desc":""},"vip":{"vipType":0,"vipDueDate":0,"dueRemark":"","accessStatus":1,"vipStatus":0,"vipStatusWarn":""}}`) |
|
|
|
// Service is reply service |
|
type Service struct { |
|
sndDefCnt int |
|
oneDaySec int // If block time from word filter is greater than one day, then banned reply and add moral to account. |
|
useBigData bool |
|
// content filter |
|
bigdata *bigdata.Dao |
|
|
|
drawyoo *drawyoo.Dao |
|
|
|
// fans http get method |
|
fans *fans.Dao |
|
|
|
// http request |
|
search *search.Dao |
|
|
|
// rpc client |
|
acc accrpc.AccountClient |
|
feedClient replyfeed.ReplyFeedClient |
|
filcli filgrpc.FilterClient |
|
location *locrpc.Service |
|
assist *assrpc.Service |
|
figure *figrpc.Service |
|
thumbup thumbup.ThumbupRPC |
|
// seq rpc |
|
seqArg *seqmdl.ArgBusiness |
|
seqSrv *seqrpc.Service2 |
|
// workflow dao |
|
workflow *workflow.Dao |
|
arcSrv *arcrpc.Service2 |
|
articleSrv *artrpc.Service |
|
ugcpay ugcpay.UGCPayClient |
|
// reply cache dao |
|
dao *reply.Dao |
|
// asynchronized add cache use channel |
|
replyChan chan replyChan |
|
topRpChan chan topRpChan |
|
// vip |
|
vip *vip.Dao |
|
emojisM map[string]int64 |
|
emojis []*model.EmojiPackage |
|
// reply notice |
|
notice map[int8][]*model.Notice |
|
// default member |
|
defMember *model.Info |
|
cache *fanout.Fanout |
|
|
|
typeMapping map[int32]string |
|
aliasMapping map[string]int32 |
|
aidWhiteList []int64 |
|
|
|
infoc *infoc.Infoc |
|
bnjAid map[int64]struct{} |
|
sortByHot map[int64]int8 |
|
sortByTime map[int64]int8 |
|
hideFloor map[int64]int8 |
|
hotReplyConfig map[int8]map[int64]int |
|
} |
|
|
|
// New new a service |
|
func New(c *conf.Config) (s *Service) { |
|
s = &Service{ |
|
cache: fanout.New("cache", fanout.Worker(1), fanout.Buffer(1024)), |
|
sndDefCnt: conf.Conf.Reply.SecondDefSize, |
|
oneDaySec: 24 * 60 * 60, |
|
useBigData: conf.Conf.Reply.BigdataFilter, |
|
replyChan: make(chan replyChan, _replyChanBuf), |
|
topRpChan: make(chan topRpChan, _topRpChanBuf), |
|
aidWhiteList: c.Reply.AidWhiteList, |
|
arcSrv: arcrpc.New2(c.RPCClient2.Archive), |
|
articleSrv: artrpc.New(c.RPCClient2.Article), |
|
infoc: infoc.New(c.Infoc), |
|
bnjAid: make(map[int64]struct{}), |
|
sortByTime: make(map[int64]int8), |
|
sortByHot: make(map[int64]int8), |
|
hideFloor: make(map[int64]int8), |
|
hotReplyConfig: make(map[int8]map[int64]int), |
|
} |
|
for oidStr, tp := range c.Reply.SortByHotOids { |
|
var ( |
|
oid int64 |
|
err error |
|
) |
|
if oid, err = strconv.ParseInt(oidStr, 10, 64); err != nil { |
|
panic(err) |
|
} |
|
s.sortByHot[oid] = tp |
|
} |
|
for oidStr, tp := range c.Reply.SortByTimeOids { |
|
var ( |
|
oid int64 |
|
err error |
|
) |
|
if oid, err = strconv.ParseInt(oidStr, 10, 64); err != nil { |
|
panic(err) |
|
} |
|
s.sortByTime[oid] = tp |
|
} |
|
for oidStr, tp := range c.Reply.HideFloorOids { |
|
var ( |
|
oid int64 |
|
err error |
|
) |
|
if oid, err = strconv.ParseInt(oidStr, 10, 64); err != nil { |
|
panic(err) |
|
} |
|
s.hideFloor[oid] = tp |
|
} |
|
for tpStr, mapping := range c.Reply.HotReplyConfig { |
|
var ( |
|
tp int64 |
|
oid int64 |
|
err error |
|
) |
|
if tp, err = strconv.ParseInt(tpStr, 10, 64); err != nil { |
|
panic(err) |
|
} |
|
businessConfig := make(map[int64]int) |
|
for oidStr, num := range mapping { |
|
if oid, err = strconv.ParseInt(oidStr, 10, 64); err != nil { |
|
panic(err) |
|
} |
|
businessConfig[oid] = num |
|
} |
|
s.hotReplyConfig[int8(tp)] = businessConfig |
|
} |
|
for _, oid := range c.Reply.BnjAidList { |
|
s.bnjAid[oid] = struct{}{} |
|
} |
|
acc, err := accrpc.NewClient(c.AccountGRPCClient) |
|
if err != nil { |
|
panic(err) |
|
} |
|
s.acc = acc |
|
filcli, err := filgrpc.NewClient(c.FilterGRPCClient) |
|
if err != nil { |
|
panic(err) |
|
} |
|
s.filcli = filcli |
|
feedClient, err := replyfeed.NewClient(c.FeedGRPCClient) |
|
if err != nil { |
|
panic(err) |
|
} |
|
s.feedClient = feedClient |
|
// init depend dao |
|
s.fans = fans.New(c) |
|
s.search = search.New(c) |
|
s.drawyoo = drawyoo.New(c) |
|
s.bigdata = bigdata.New(c) |
|
s.vip = vip.New(c) |
|
s.emojisM = make(map[string]int64) |
|
s.emojis = make([]*model.EmojiPackage, 0) |
|
// init rpc client |
|
s.location = locrpc.New(c.RPCClient2.Location) |
|
s.assist = assrpc.New(c.RPCClient2.Assist) |
|
s.figure = figrpc.New(c.RPCClient2.Figure) |
|
s.seqSrv = seqrpc.New2(c.RPCClient2.Seq) |
|
s.seqArg = &seqmdl.ArgBusiness{Token: c.Seq.Token, BusinessID: c.Seq.BusinessID} |
|
s.thumbup = thumbup.New(c.RPCClient2.Thumbup) |
|
s.workflow = workflow.New(c) |
|
s.ugcpay, err = ugcpay.NewClient(nil) |
|
if err != nil { |
|
panic(err) |
|
} |
|
// init reply cache dao |
|
s.dao = reply.New(c) |
|
// default member |
|
s.defMember = &model.Info{} |
|
s.typeMapping = make(map[int32]string) |
|
s.aliasMapping = make(map[string]int32) |
|
if err := json.Unmarshal(_defMemberJSON, s.defMember); err != nil { |
|
panic(err) |
|
} |
|
for i := 0; i < runtime.NumCPU(); i++ { |
|
go s.cacheproc() |
|
} |
|
s.loadEmoji() |
|
s.loadRplNotice() |
|
s.loadBusiness() |
|
go s.loadproc() |
|
return |
|
} |
|
|
|
// TypeToAlias map type to alias |
|
func (s *Service) TypeToAlias(t int32) (alias string, exists bool) { |
|
alias, exists = s.typeMapping[t] |
|
return |
|
} |
|
|
|
// AliasToType map alias to type |
|
func (s *Service) AliasToType(alias string) (t int32, exists bool) { |
|
t, exists = s.aliasMapping[alias] |
|
return |
|
} |
|
|
|
func (s *Service) loadproc() { |
|
for { |
|
s.loadEmoji() |
|
s.loadRplNotice() |
|
s.loadBusiness() |
|
time.Sleep(time.Duration(conf.Conf.Reply.EmojiExpire)) |
|
} |
|
} |
|
|
|
// Ping check service health |
|
func (s *Service) Ping(c context.Context) (err error) { |
|
return s.dao.Ping(c) |
|
} |
|
|
|
// Close close service connection |
|
func (s *Service) Close() { |
|
s.dao.Close() |
|
} |
|
|
|
// ResetFloor ... |
|
func (s *Service) ResetFloor(rps ...*model.Reply) { |
|
for _, rp := range rps { |
|
if rp == nil { |
|
continue |
|
} |
|
rp.Floor = 0 |
|
if rp.Replies == nil { |
|
continue |
|
} |
|
for _, childRp := range rp.Replies { |
|
if childRp == nil { |
|
continue |
|
} |
|
childRp.Floor = 0 |
|
} |
|
} |
|
} |
|
|
|
// hotNum ... |
|
func (s *Service) hotNumWeb(oid int64, tp int8) int { |
|
if businessConfig, ok := s.hotReplyConfig[tp]; ok { |
|
if num, exists := businessConfig[oid]; exists { |
|
return num |
|
} |
|
} |
|
return _hotSizeWeb |
|
} |
|
|
|
// hotNum ... |
|
func (s *Service) hotNum(oid int64, tp int8) int { |
|
if businessConfig, ok := s.hotReplyConfig[tp]; ok { |
|
if num, exists := businessConfig[oid]; exists { |
|
return num |
|
} |
|
} |
|
return _hotSize |
|
} |
|
|
|
// IsBnj avid... |
|
func (s *Service) IsBnj(oid int64, tp int8) bool { |
|
if _, ok := s.bnjAid[oid]; ok && tp == model.SubTypeArchive { |
|
return true |
|
} |
|
return false |
|
} |
|
|
|
// ShowFloor ... |
|
func (s *Service) ShowFloor(oid int64, tp int8) bool { |
|
if typ, ok := s.hideFloor[oid]; ok && typ == tp { |
|
return false |
|
} |
|
return true |
|
} |
|
|
|
// loadEmoji load emoji |
|
func (s *Service) loadEmoji() (err error) { |
|
var ( |
|
emojis = make([]*model.EmojiPackage, 0) |
|
c = context.Background() |
|
emjM = make(map[string]int64) |
|
) |
|
emjs, err := s.dao.Emoji.ListEmojiPack(c) |
|
if err != nil { |
|
log.Error("service.ListEmojiPack error (%v)", err) |
|
return err |
|
} |
|
for _, d := range emjs { |
|
d.Emojis, err = s.dao.Emoji.EmojiListByPid(c, d.ID) |
|
if err != nil { |
|
log.Error("service.EmojiListByPid err (%v)", err) |
|
return err |
|
} |
|
for _, emo := range d.Emojis { |
|
emjM[emo.Name] = emo.ID |
|
} |
|
if len(d.Emojis) > 0 { |
|
emojis = append(emojis, d) |
|
} |
|
} |
|
s.emojis = emojis |
|
s.emojisM = emjM |
|
return |
|
}
|
|
|