123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- package version
- import (
- "context"
- "time"
- "go-common/app/interface/main/app-resource/conf"
- verdao "go-common/app/interface/main/app-resource/dao/version"
- "go-common/app/interface/main/app-resource/model"
- "go-common/app/interface/main/app-resource/model/version"
- "go-common/library/ecode"
- "go-common/library/log"
- farm "github.com/dgryski/go-farm"
- )
- const (
- _defaultChannel = "bili"
- )
- var (
- _emptyVersion = []*version.Version{}
- _emptyVersionSo = []*version.VersionSo{}
- )
- // Service version service.
- type Service struct {
- dao *verdao.Dao
- cache map[int8][]*version.Version
- upCache map[int8]map[string][]*version.VersionUpdate
- uplimitCache map[int][]*version.UpdateLimit
- soCache map[string][]*version.VersionSo
- increCache map[int8]map[string][]*version.Incremental
- rnCache map[string]map[string]*version.Rn
- tick time.Duration
- }
- // New new a version service.
- func New(c *conf.Config) (s *Service) {
- s = &Service{
- dao: verdao.New(c),
- tick: time.Duration(c.Tick),
- cache: map[int8][]*version.Version{},
- upCache: map[int8]map[string][]*version.VersionUpdate{},
- uplimitCache: map[int][]*version.UpdateLimit{},
- soCache: map[string][]*version.VersionSo{},
- increCache: map[int8]map[string][]*version.Incremental{},
- rnCache: map[string]map[string]*version.Rn{},
- }
- s.load()
- go s.loadproc()
- return
- }
- // Version return version
- func (s *Service) Version(plat int8) (res []*version.Version, err error) {
- if res = s.cache[plat]; res == nil {
- res = _emptyVersion
- }
- return
- }
- // VersionUpdate return version
- func (s *Service) VersionUpdate(build int, plat int8, buvid, sdkint, channel, module, oldID string) (res *version.VersionUpdate, err error) {
- var (
- gvu, tmp []*version.VersionUpdate
- )
- if vup, ok := s.upCache[plat]; ok {
- if tmp, ok = vup[channel]; !ok || len(tmp) == 0 {
- if plat == model.PlatAndroidTVYST {
- err = ecode.NotModified
- return
- }
- if tmp, ok = vup[_defaultChannel]; !ok || len(tmp) == 0 {
- err = ecode.NotModified
- return
- }
- }
- for _, t := range tmp {
- tu := &version.VersionUpdate{}
- *tu = *t
- gvu = append(gvu, tu)
- }
- } else {
- err = ecode.NotModified
- return
- }
- LOOP:
- for _, vu := range gvu {
- if build >= vu.Build {
- err = ecode.NotModified
- return
- }
- if vu.IsGray == 1 {
- if len(vu.SdkIntList) > 0 {
- if _, ok := vu.SdkIntList[sdkint]; !ok {
- continue LOOP
- }
- }
- if module != vu.Model && vu.Model != "" {
- continue LOOP
- }
- if buvid != "" {
- id := farm.Hash32([]byte(buvid))
- n := int(id % 100)
- if vu.BuvidStart > n || n > vu.BuvidEnd {
- continue LOOP
- }
- }
- }
- if limit, ok := s.uplimitCache[vu.Id]; ok {
- var tmpl bool
- for i, l := range limit {
- if i+1 <= len(limit)-1 {
- if ((l.Conditions == "gt" && limit[i+1].Conditions == "lt") && (l.BuildLimit < limit[i+1].BuildLimit)) ||
- ((l.Conditions == "lt" && limit[i+1].Conditions == "gt") && (l.BuildLimit > limit[i+1].BuildLimit)) {
- if (l.Conditions == "gt" && limit[i+1].Conditions == "lt") &&
- (build > l.BuildLimit && build < limit[i+1].BuildLimit) {
- res = vu
- break LOOP
- } else if (l.Conditions == "lt" && limit[i+1].Conditions == "gt") &&
- (build < l.BuildLimit && build > limit[i+1].BuildLimit) {
- res = vu
- break LOOP
- } else {
- tmpl = true
- continue
- }
- }
- }
- if tmpl {
- tmpl = false
- continue
- }
- if model.InvalidBuild(build, l.BuildLimit, l.Conditions) {
- continue
- } else {
- res = vu
- break LOOP
- }
- }
- } else {
- res = vu
- break LOOP
- }
- }
- if res == nil {
- err = ecode.NotModified
- return
- }
- res.Incre = s.versionIncrementals(plat, res.Build, oldID)
- return
- }
- // versionIncrementals version incrementals
- func (s *Service) versionIncrementals(plat int8, build int, oldID string) (ver *version.Incremental) {
- if v, ok := s.increCache[plat]; ok {
- if vers, ok := v[oldID]; ok {
- for _, value := range vers {
- if value.Build == build {
- ver = value
- return
- }
- }
- }
- }
- return
- }
- // VersionSo return version_so
- func (s *Service) VersionSo(build, seed, sdkint int, name, model string) (vsdesc *version.VersionSoDesc, err error) {
- vSo := s.soCache[name]
- if len(vSo) == 0 {
- err = ecode.NotModified
- return
- }
- vsdesc = &version.VersionSoDesc{
- Package: vSo[0].Package,
- Name: vSo[0].Name,
- Description: vSo[0].Description,
- Clear: vSo[0].Clear,
- }
- for _, value := range vSo {
- if value.Min_build > build || (seed > 0 && seed%100 >= value.Coverage) || (sdkint != value.Sdkint && value.Sdkint != 0) || (model != value.Model && value.Model != "" && value.Model != "*") {
- continue
- }
- vsdesc.Versions = append(vsdesc.Versions, value)
- }
- if vsdesc.Versions == nil {
- vsdesc.Versions = _emptyVersionSo
- }
- return
- }
- // VersionRn return version_rn
- func (s *Service) VersionRn(version, deploymentKey, bundleID string) (vrn *version.Rn, err error) {
- if v, ok := s.rnCache[deploymentKey]; ok {
- if vrn, ok = v[version]; !ok {
- err = ecode.NotModified
- } else if vrn.BundleID == bundleID {
- err = ecode.NotModified
- }
- } else {
- err = ecode.NotModified
- }
- return
- }
- // load cache data
- func (s *Service) load() {
- ver, err := s.dao.All(context.TODO())
- if err != nil {
- log.Error("version s.dao.All() error(%v)", err)
- return
- }
- s.cache = ver
- upver, err := s.dao.Updates(context.TODO())
- if err != nil {
- log.Error("version s.dao.GetUpdate() error(%v)", err)
- return
- }
- s.upCache = upver
- log.Info("version cacheproc success")
- sover, err := s.dao.Sos(context.TODO())
- if err != nil {
- log.Error("version s.dao.Sos() error(%v)", err)
- return
- }
- uplimit, err := s.dao.Limits(context.TODO())
- if err != nil {
- log.Error("version s.dao.Limits() error(%v)", err)
- return
- }
- s.uplimitCache = uplimit
- s.soCache = sover
- log.Info("versionso cacheproc success")
- increver, err := s.dao.Incrementals(context.TODO())
- if err != nil {
- log.Error("version s.dao.Incrementals error(%v)", err)
- return
- }
- s.increCache = increver
- log.Info("versionIncre cacheproc success")
- rn, err := s.dao.Rn(context.TODO())
- if err != nil {
- log.Error("version s.dao.Rn error(%v)", err)
- return
- }
- s.rnCache = rn
- log.Info("versionRn cacheproc success")
- }
- // cacheproc load cache data
- func (s *Service) loadproc() {
- for {
- time.Sleep(s.tick)
- s.load()
- }
- }
- // Close dao
- func (s *Service) Close() {
- s.dao.Close()
- }
|