178 lines
4.1 KiB
Go
178 lines
4.1 KiB
Go
|
package service
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"sync"
|
|||
|
"time"
|
|||
|
|
|||
|
"go-common/app/interface/main/push-archive/conf"
|
|||
|
"go-common/app/interface/main/push-archive/dao"
|
|||
|
"go-common/app/interface/main/push-archive/model"
|
|||
|
accrpc "go-common/app/service/main/account/rpc/client"
|
|||
|
pb "go-common/app/service/main/push/api/grpc/v1"
|
|||
|
pushrpc "go-common/app/service/main/push/api/grpc/v1"
|
|||
|
"go-common/library/cache"
|
|||
|
"go-common/library/conf/env"
|
|||
|
"go-common/library/log"
|
|||
|
bm "go-common/library/net/http/blademaster"
|
|||
|
"go-common/library/queue/databus"
|
|||
|
)
|
|||
|
|
|||
|
// Service push service.
|
|||
|
type Service struct {
|
|||
|
c *conf.Config
|
|||
|
dao *dao.Dao
|
|||
|
cache *cache.Cache
|
|||
|
accRPC *accrpc.Service3
|
|||
|
wg sync.WaitGroup
|
|||
|
archiveSub *databus.Databus
|
|||
|
relationSub *databus.Databus
|
|||
|
userSettings map[int64]*model.Setting
|
|||
|
arcMo, relMo int64
|
|||
|
CloseCh chan bool
|
|||
|
ForbidTimes []conf.ForbidTime
|
|||
|
settingCh chan *pb.SetSettingRequest
|
|||
|
pushRPC pushrpc.PushClient
|
|||
|
}
|
|||
|
|
|||
|
// New creates a push service instance.
|
|||
|
func New(c *conf.Config) *Service {
|
|||
|
s := &Service{
|
|||
|
c: c,
|
|||
|
dao: dao.New(c),
|
|||
|
cache: cache.New(1, 102400),
|
|||
|
accRPC: accrpc.New3(c.AccountRPC),
|
|||
|
archiveSub: databus.New(c.ArchiveSub),
|
|||
|
relationSub: databus.New(c.RelationSub),
|
|||
|
userSettings: make(map[int64]*model.Setting),
|
|||
|
CloseCh: make(chan bool),
|
|||
|
ForbidTimes: c.ArcPush.ForbidTimes,
|
|||
|
settingCh: make(chan *pb.SetSettingRequest, 3072),
|
|||
|
}
|
|||
|
var err error
|
|||
|
if s.pushRPC, err = pushrpc.NewClient(c.PushRPC); err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
s.mappingAbtest()
|
|||
|
go s.loadUserSettingsproc()
|
|||
|
time.Sleep(2 * time.Second) // consumeArchive will notice upper's fans, it depends on user's setting
|
|||
|
s.wg.Add(1)
|
|||
|
go s.loadUserSettingsproc()
|
|||
|
if c.Push.ProdSwitch {
|
|||
|
s.wg.Add(1)
|
|||
|
go s.consumeRelationproc()
|
|||
|
s.wg.Add(1)
|
|||
|
go s.consumeArchiveproc()
|
|||
|
go s.monitorConsume()
|
|||
|
}
|
|||
|
go s.clearStatisticsProc()
|
|||
|
s.wg.Add(1)
|
|||
|
go s.saveStatisticsProc()
|
|||
|
go s.setSettingProc()
|
|||
|
return s
|
|||
|
}
|
|||
|
|
|||
|
// loadUserSettingsproc 若是用户没有设置推送开关,默认会被推送消息;因此,若是新设置load出错/无值,则不替换旧设置
|
|||
|
func (s *Service) loadUserSettingsproc() {
|
|||
|
defer s.wg.Done()
|
|||
|
var (
|
|||
|
ps int64 = 30000
|
|||
|
start int64
|
|||
|
end int64
|
|||
|
mxID int64
|
|||
|
err error
|
|||
|
res map[int64]*model.Setting
|
|||
|
)
|
|||
|
|
|||
|
for {
|
|||
|
select {
|
|||
|
case _, ok := <-s.CloseCh:
|
|||
|
if !ok {
|
|||
|
log.Info("CloseCh is closed, close the loadUserSettingsproc")
|
|||
|
return
|
|||
|
}
|
|||
|
default:
|
|||
|
}
|
|||
|
|
|||
|
start = 0
|
|||
|
end = 0
|
|||
|
err = nil
|
|||
|
res = make(map[int64]*model.Setting)
|
|||
|
mxID, err = s.dao.SettingsMaxID(context.TODO())
|
|||
|
if err != nil || mxID == 0 {
|
|||
|
time.Sleep(10 * time.Millisecond)
|
|||
|
continue
|
|||
|
}
|
|||
|
|
|||
|
for {
|
|||
|
start = end
|
|||
|
end += ps
|
|||
|
err = s.dao.SettingsAll(context.TODO(), start, end, &res)
|
|||
|
if err != nil {
|
|||
|
break
|
|||
|
}
|
|||
|
if end >= mxID {
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if err != nil || len(res) == 0 {
|
|||
|
time.Sleep(10 * time.Millisecond)
|
|||
|
continue
|
|||
|
}
|
|||
|
s.userSettings = res
|
|||
|
time.Sleep(time.Duration(s.c.Push.LoadSettingsInterval))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (s *Service) monitorConsume() {
|
|||
|
if env.DeployEnv != env.DeployEnvProd {
|
|||
|
return
|
|||
|
}
|
|||
|
var (
|
|||
|
arc int64 // archive result count
|
|||
|
rel int64 // relation count
|
|||
|
)
|
|||
|
for {
|
|||
|
time.Sleep(10 * time.Minute)
|
|||
|
if s.arcMo-arc == 0 {
|
|||
|
msg := "databus: push-archive archiveResult did not consume within ten minute"
|
|||
|
s.dao.WechatMessage(msg)
|
|||
|
log.Warn(msg)
|
|||
|
}
|
|||
|
arc = s.arcMo
|
|||
|
if s.relMo-rel == 0 {
|
|||
|
msg := "databus: push-archive relation did not consume within ten minute"
|
|||
|
s.dao.WechatMessage(msg)
|
|||
|
log.Warn(msg)
|
|||
|
}
|
|||
|
rel = s.relMo
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Close closes service.
|
|||
|
func (s *Service) Close() {
|
|||
|
s.archiveSub.Close()
|
|||
|
s.relationSub.Close()
|
|||
|
close(s.CloseCh)
|
|||
|
s.wg.Wait()
|
|||
|
s.dao.Close()
|
|||
|
}
|
|||
|
|
|||
|
// Ping checks service.
|
|||
|
func (s *Service) Ping(c *bm.Context) (err error) {
|
|||
|
err = s.dao.Ping(c)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// getTodayTime 获取当日的某个时间点的时间
|
|||
|
func (s *Service) getTodayTime(tm string) (todayTime time.Time, err error) {
|
|||
|
now := time.Now()
|
|||
|
today := now.Format("2006-01-02")
|
|||
|
todayTime, err = time.ParseInLocation("2006-01-02 15:04:05", today+" "+tm, time.Local)
|
|||
|
if err != nil {
|
|||
|
log.Error("clearStatisticsProc time.ParseInLocation error(%v)", err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|