123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- 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
- }
|