127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"time"
|
||
|
|
||
|
"go-common/app/interface/main/answer/conf"
|
||
|
"go-common/app/interface/main/answer/dao"
|
||
|
accountDao "go-common/app/interface/main/answer/dao/account"
|
||
|
geetestDao "go-common/app/interface/main/answer/dao/geetest"
|
||
|
"go-common/app/interface/main/answer/model"
|
||
|
accoutCli "go-common/app/service/main/account/api"
|
||
|
memrpc "go-common/app/service/main/member/api/gorpc"
|
||
|
"go-common/library/log"
|
||
|
"go-common/library/log/anticheat"
|
||
|
"go-common/library/queue/databus/report"
|
||
|
"go-common/library/stat/prom"
|
||
|
"go-common/library/sync/pipeline/fanout"
|
||
|
)
|
||
|
|
||
|
// Service struct of service.
|
||
|
type Service struct {
|
||
|
c *conf.Config
|
||
|
answerDao *dao.Dao
|
||
|
geetestDao *geetestDao.Dao
|
||
|
accountDao *accountDao.Dao
|
||
|
accountSvc accoutCli.AccountClient
|
||
|
memRPC *memrpc.Service
|
||
|
missch *fanout.Fanout
|
||
|
beformalch chan *model.Formal
|
||
|
questionTypeCache map[int64]*model.TypeInfo
|
||
|
rankCache []*model.RankInfo
|
||
|
mRankCache []*model.RankInfo
|
||
|
tcQestTick time.Duration
|
||
|
rankQuestTick time.Duration
|
||
|
promBeFormal *prom.Prom
|
||
|
|
||
|
infoc2 *anticheat.AntiCheat
|
||
|
}
|
||
|
|
||
|
// New create service instance and return.
|
||
|
func New(c *conf.Config) (s *Service) {
|
||
|
s = &Service{
|
||
|
c: c,
|
||
|
answerDao: dao.New(c),
|
||
|
geetestDao: geetestDao.New(c),
|
||
|
accountDao: accountDao.New(c),
|
||
|
memRPC: memrpc.New(c.RPCClient.Member),
|
||
|
missch: fanout.New("cache", fanout.Worker(1), fanout.Buffer(1024)),
|
||
|
beformalch: make(chan *model.Formal, 1024),
|
||
|
questionTypeCache: map[int64]*model.TypeInfo{},
|
||
|
rankCache: []*model.RankInfo{},
|
||
|
mRankCache: []*model.RankInfo{},
|
||
|
tcQestTick: time.Duration(c.Question.TcQestTick),
|
||
|
rankQuestTick: time.Duration(c.Question.RankQestTick),
|
||
|
promBeFormal: prom.New().WithCounter("answer_beformal_count", []string{"name"}),
|
||
|
}
|
||
|
accountSvc, err := accoutCli.NewClient(c.AccountRPC)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
s.accountSvc = accountSvc
|
||
|
s.loadQidsCache()
|
||
|
s.loadExtraQidsCache()
|
||
|
s.loadtypes()
|
||
|
go s.rankcacheproc()
|
||
|
go s.beformalproc()
|
||
|
if c.Infoc2 != nil {
|
||
|
s.infoc2 = anticheat.New(c.Infoc2)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) addRetryBeFormal(msg *model.Formal) {
|
||
|
select {
|
||
|
case s.beformalch <- msg:
|
||
|
default:
|
||
|
log.Warn("beformalch chan full")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Service) beformalproc() {
|
||
|
var (
|
||
|
err error
|
||
|
c = context.Background()
|
||
|
msg *model.Formal
|
||
|
)
|
||
|
for {
|
||
|
msg = <-s.beformalch
|
||
|
for retries := 0; retries < s.c.Answer.MaxRetries; retries++ {
|
||
|
if err = s.accountDao.BeFormal(c, msg.Mid, msg.IP); err != nil {
|
||
|
sleep := s.c.Backoff.Backoff(retries)
|
||
|
log.Error("beFormal fail(%d) sleep(%d) err(%+v)", msg.Mid, sleep, err)
|
||
|
time.Sleep(sleep * time.Second)
|
||
|
continue
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Close dao.
|
||
|
func (s *Service) Close() {
|
||
|
s.answerDao.Close()
|
||
|
}
|
||
|
|
||
|
func (s *Service) rankcacheproc() {
|
||
|
for {
|
||
|
time.Sleep(s.tcQestTick)
|
||
|
s.loadtypes()
|
||
|
s.loadQidsCache()
|
||
|
s.loadExtraQidsCache()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Service) userActionLog(mid int64, typ string, ah *model.AnswerHistory) {
|
||
|
report.User(&report.UserInfo{
|
||
|
Mid: mid,
|
||
|
Business: model.AnswerLogID,
|
||
|
Action: model.AnswerUpdate,
|
||
|
Ctime: time.Now(),
|
||
|
Content: map[string]interface{}{
|
||
|
typ: ah,
|
||
|
},
|
||
|
})
|
||
|
}
|