123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- package module
- import (
- "context"
- "strconv"
- "strings"
- "time"
- "go-common/app/interface/main/app-resource/conf"
- moduledao "go-common/app/interface/main/app-resource/dao/module"
- "go-common/app/interface/main/app-resource/model/module"
- "go-common/library/ecode"
- "go-common/library/log"
- )
- var (
- _emptylist = []*module.ResourcePool{}
- )
- // Service module service.
- type Service struct {
- dao *moduledao.Dao
- tick time.Duration
- resourceCache map[string]*module.ResourcePool
- conditionsCache map[int]*module.Condition
- }
- // New new a module service.
- func New(c *conf.Config) (s *Service) {
- s = &Service{
- dao: moduledao.New(c),
- tick: time.Duration(c.Tick),
- resourceCache: map[string]*module.ResourcePool{},
- conditionsCache: make(map[int]*module.Condition),
- }
- s.loadCache()
- go s.loadproc()
- return
- }
- func (s *Service) FormCondition(versions []*module.Versions) (res map[string]map[string]int) {
- res = make(map[string]map[string]int)
- for _, pools := range versions {
- var (
- re map[string]int
- ok bool
- )
- for _, resource := range pools.Resource {
- if re, ok = res[pools.PoolName]; !ok {
- re = make(map[string]int)
- res[pools.PoolName] = re
- }
- var tmpVer int
- switch tmp := resource.Version.(type) {
- case string:
- tmpVer, _ = strconv.Atoi(tmp)
- case float64:
- tmpVer = int(tmp)
- }
- re[resource.ResourceName] = tmpVer
- }
- }
- return
- }
- // List get All or by poolname
- func (s *Service) List(c context.Context, mobiApp, device, platform, poolName, env string, build, sysver, level, scale, arch int,
- versions []*module.Versions, now time.Time) (res []*module.ResourcePool) {
- var (
- resTmp []*module.ResourcePool
- versionsMap = s.FormCondition(versions)
- )
- if poolName != "" {
- if pool, ok := s.resourceCache[poolName]; ok {
- resTmp = append(resTmp, pool)
- }
- } else {
- for _, l := range s.resourceCache {
- resTmp = append(resTmp, l)
- }
- }
- if len(resTmp) == 0 {
- res = _emptylist
- return
- }
- for _, resPool := range resTmp {
- var (
- existRes = map[string]*module.Resource{}
- existResTotal = map[string]struct{}{}
- resPoolTmp = &module.ResourcePool{Name: resPool.Name}
- ok bool
- )
- for _, re := range resPool.Resources {
- if re == nil {
- continue
- }
- if !s.checkCondition(c, mobiApp, device, platform, env, build, sysver, level, scale, arch, re.Condition, now) {
- continue
- }
- var t *module.Resource
- if _, ok = existResTotal[re.Name]; ok {
- continue
- }
- if t, ok = existRes[re.Name]; ok {
- if re.Increment == module.Total {
- tmp := &module.Resource{}
- *tmp = *t
- tmp.TotalMD5 = re.MD5
- existResTotal[tmp.Name] = struct{}{}
- resPoolTmp.Resources = append(resPoolTmp.Resources, tmp)
- continue
- }
- } else {
- var (
- resVer map[string]int
- ver int
- )
- if resVer, ok = versionsMap[resPool.Name]; ok {
- if ver, ok = resVer[re.Name]; ok {
- if re.Increment == module.Incremental && re.FromVer != ver {
- continue
- }
- } else if !ok && re.Increment == module.Incremental {
- continue
- }
- } else if !ok && re.Increment == module.Incremental {
- continue
- }
- tmp := &module.Resource{}
- *tmp = *re
- existRes[tmp.Name] = tmp
- if re.Increment == module.Total {
- tmp.TotalMD5 = re.MD5
- existResTotal[tmp.Name] = struct{}{}
- resPoolTmp.Resources = append(resPoolTmp.Resources, tmp)
- }
- }
- }
- if len(resPoolTmp.Resources) == 0 {
- continue
- }
- res = append(res, resPoolTmp)
- }
- return
- }
- // Resource get by poolname and resourcename
- func (s *Service) Resource(c context.Context, mobiApp, device, platform, poolName, resourceName, env string,
- ver, build, sysver, level, scale, arch int, now time.Time) (res *module.Resource, err error) {
- if resPoolTmp, ok := s.resourceCache[poolName]; ok {
- if resPoolTmp == nil {
- err = ecode.NothingFound
- return
- }
- var (
- resTmp *module.Resource
- existRes = map[string]struct{}{}
- )
- for _, resTmp = range resPoolTmp.Resources {
- if resTmp == nil {
- continue
- }
- if resTmp != nil && resTmp.Name == resourceName {
- if !s.checkCondition(c, mobiApp, device, platform, env, build, sysver, level, scale, arch, resTmp.Condition, now) {
- continue
- }
- if ver == 0 {
- if resTmp.Increment == module.Incremental {
- continue
- }
- } else {
- if resTmp.Increment == module.Incremental && resTmp.FromVer != ver {
- continue
- }
- }
- if resTmp.Increment == module.Total && resTmp.Version == ver {
- err = ecode.NotModified
- break
- }
- if _, ok := existRes[resTmp.Name]; !ok {
- res = &module.Resource{}
- *res = *resTmp
- existRes[resTmp.Name] = struct{}{}
- }
- if resTmp.Increment == module.Total && res != nil {
- res.TotalMD5 = resTmp.MD5
- break
- }
- }
- }
- }
- if err != nil {
- return
- }
- if res == nil {
- err = ecode.NothingFound
- }
- return
- }
- func (s *Service) checkCondition(c context.Context, mobiApp, device, platform, env string, build, sysver, level, scale, arch int, condition *module.Condition, now time.Time) bool {
- if condition == nil {
- return true
- }
- if env == module.EnvRelease && condition.Valid == 0 {
- return false
- } else if env == module.EnvTest && condition.ValidTest == 0 {
- return false
- } else if env == module.EnvDefault && condition.Default != 1 {
- return false
- }
- if !condition.STime.Time().IsZero() && now.Unix() < int64(condition.STime) {
- return false
- }
- if !condition.ETime.Time().IsZero() && now.Unix() > int64(condition.ETime) {
- return false
- }
- NETX:
- for column, cv := range condition.Columns {
- switch column {
- case "plat": // whith list
- for _, v := range cv {
- if strings.TrimSpace(v.Value) == platform {
- continue NETX
- }
- }
- return false
- case "mobi_app": // whith list
- for _, v := range cv {
- if strings.TrimSpace(v.Value) == mobiApp {
- continue NETX
- }
- }
- return false
- case "device": // blace list
- for _, v := range cv {
- if strings.TrimSpace(v.Value) == device {
- return false
- }
- }
- case "build": // build < lt gt > build ge >= build, le <= build
- for _, v := range cv {
- value, _ := strconv.Atoi(strings.TrimSpace(v.Value))
- if invalidModelBuild(build, value, v.Condition) {
- return false
- }
- }
- case "sysver":
- if sysver > 0 {
- for _, v := range cv {
- value, _ := strconv.Atoi(strings.TrimSpace(v.Value))
- if invalidModelBuild(sysver, value, v.Condition) {
- return false
- }
- }
- }
- case "scale": // whith list
- if scale > 0 {
- for _, v := range cv {
- value, _ := strconv.Atoi(strings.TrimSpace(v.Value))
- if value == scale {
- continue NETX
- }
- }
- return false
- }
- case "arch": // whith list
- if arch > 0 {
- for _, v := range cv {
- value, _ := strconv.Atoi(strings.TrimSpace(v.Value))
- if value == arch {
- continue NETX
- }
- }
- return false
- }
- }
- }
- return true
- }
- // ModuleUpdateCache update module cache
- func (s *Service) ModuleUpdateCache() (err error) {
- err = s.loadCache()
- return
- }
- // load update cache
- func (s *Service) loadCache() (err error) {
- configsTmp, err := s.dao.ResourceConfig(context.TODO())
- if err != nil {
- log.Error("s.dao.ResourceConfig error(%v)", err)
- return
- }
- limitTmp, err := s.dao.ResourceLimit(context.TODO())
- if err != nil {
- log.Error("s.dao.ResourceLimit error(%v)", err)
- return
- }
- for _, config := range configsTmp {
- if limit, ok := limitTmp[config.ID]; ok {
- config.Columns = limit
- }
- }
- s.conditionsCache = configsTmp
- log.Info("module conditions success")
- tmpResourceDev, err := s.dao.ModuleDev(context.TODO())
- if err != nil {
- log.Error("s.dao.ModuleDev error(%v)", err)
- return
- }
- tmpResources, err := s.dao.ModuleAll(context.TODO())
- if err != nil {
- log.Error("s.dao.ModuleAll error(%v)", err)
- return
- }
- tmpResourcePoolCaches := map[string]*module.ResourcePool{}
- for _, resPool := range tmpResourceDev {
- if resPool == nil {
- continue
- }
- var tmpResourcePoolCache = &module.ResourcePool{ID: resPool.ID, Name: resPool.Name}
- for _, res := range resPool.Resources {
- if res == nil {
- continue
- }
- if re, ok := tmpResources[res.ID]; ok {
- var tmpre []*module.Resource
- for _, r := range re {
- if r.URL == "" || r.MD5 == "" {
- continue
- }
- if c, ok := s.conditionsCache[r.ResID]; ok {
- r.Condition = c
- // all level
- if c != nil {
- for column, cv := range c.Columns {
- switch column {
- case "level":
- for _, v := range cv {
- value, _ := strconv.Atoi(strings.TrimSpace(v.Value))
- r.Level = value
- }
- }
- }
- }
- r.IsWifi = c.IsWifi
- }
- tmpre = append(tmpre, r)
- }
- if len(tmpre) == 0 {
- continue
- }
- tmpResourcePoolCache.Resources = append(tmpResourcePoolCache.Resources, tmpre...)
- }
- }
- tmpResourcePoolCaches[resPool.Name] = tmpResourcePoolCache
- }
- s.resourceCache = tmpResourcePoolCaches
- log.Info("module resources success")
- return
- }
- // cacheproc load cache data
- func (s *Service) loadproc() {
- for {
- time.Sleep(s.tick)
- s.loadCache()
- }
- }
- // invalidModelBuild model build
- func invalidModelBuild(srcBuild, cfgBuild int, cfgCond string) bool {
- if cfgBuild != 0 && cfgCond != "" {
- switch cfgCond {
- case "lt":
- if cfgBuild <= srcBuild {
- return true
- }
- case "le":
- if cfgBuild < srcBuild {
- return true
- }
- case "ge":
- if cfgBuild > srcBuild {
- return true
- }
- case "gt":
- if cfgBuild >= srcBuild {
- return true
- }
- }
- }
- return false
- }
|