123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package abtest
- import (
- "context"
- "time"
- "go-common/app/interface/main/app-resource/conf"
- expdao "go-common/app/interface/main/app-resource/dao/abtest"
- "go-common/app/interface/main/app-resource/model/experiment"
- "go-common/app/service/main/resource/model"
- "go-common/library/log"
- farm "github.com/dgryski/go-farm"
- )
- var (
- _emptyExperiment = []*experiment.Experiment{}
- _defaultExperiment = map[int8][]*experiment.Experiment{
- model.PlatAndroid: []*experiment.Experiment{
- &experiment.Experiment{
- ID: 10,
- Name: "默认值",
- Strategy: "default_value",
- Desc: "默认值为不匹配处理",
- TrafficGroup: "0",
- },
- },
- }
- )
- type Service struct {
- dao *expdao.Dao
- // tick
- tick time.Duration
- epm map[int8][]*experiment.Experiment
- c *conf.Config
- }
- func New(c *conf.Config) (s *Service) {
- s = &Service{
- c: c,
- dao: expdao.New(c),
- // tick
- tick: time.Duration(c.Tick),
- epm: map[int8][]*experiment.Experiment{},
- }
- s.loadAbTest()
- go s.tickproc()
- return
- }
- // TemporaryABTests 临时的各种abtest垃圾需求
- func (s *Service) TemporaryABTests(c context.Context, buvid string) (tests *experiment.ABTestV2) {
- id := farm.Hash32([]byte(buvid))
- n := int(id % 100)
- autoPlay := 1
- if n > s.c.ABTest.Range {
- autoPlay = 2
- }
- tests = &experiment.ABTestV2{
- AutoPlay: autoPlay,
- }
- return
- }
- func (s *Service) Experiment(c context.Context, plat int8, build int) (eps []*experiment.Experiment) {
- if es, ok := s.epm[plat]; ok {
- LOOP:
- for _, ep := range es {
- for _, l := range ep.Limit {
- if model.InvalidBuild(build, l.Build, l.Condition) {
- continue LOOP
- }
- }
- eps = append(eps, ep)
- }
- }
- if eps == nil {
- if es, ok := _defaultExperiment[plat]; ok {
- eps = es
- } else {
- eps = _emptyExperiment
- }
- }
- return
- }
- // tickproc tick load cache.
- func (s *Service) tickproc() {
- for {
- time.Sleep(s.tick)
- s.loadAbTest()
- }
- }
- func (s *Service) loadAbTest() {
- c := context.TODO()
- lm, err := s.dao.ExperimentLimit(c)
- if err != nil {
- log.Error("s.dao.ExperimentLimit error(%v)", err)
- return
- }
- ids := make([]int64, 0, len(lm))
- for id := range lm {
- ids = append(ids, id)
- }
- if len(ids) == 0 {
- return
- }
- eps, err := s.dao.ExperimentByIDs(c, ids)
- if err != nil {
- log.Error("s.dao.ExperimentByIDs(%v) error(%v)", ids, err)
- return
- }
- epm := make(map[int8][]*experiment.Experiment, len(eps))
- for _, ep := range eps {
- if l, ok := lm[ep.ID]; ok {
- ep.Limit = l
- }
- epm[ep.Plat] = append(epm[ep.Plat], ep)
- }
- s.epm = epm
- }
- // AbServer is
- func (s *Service) AbServer(c context.Context, buvid, device, mobiAPP, filteredStr string, build int, mid int64) (a interface{}, err error) {
- return s.dao.AbServer(c, buvid, device, mobiAPP, filteredStr, build, mid)
- }
|