version.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package version
  2. import (
  3. "context"
  4. "time"
  5. "go-common/app/interface/main/app-resource/conf"
  6. verdao "go-common/app/interface/main/app-resource/dao/version"
  7. "go-common/app/interface/main/app-resource/model"
  8. "go-common/app/interface/main/app-resource/model/version"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. farm "github.com/dgryski/go-farm"
  12. )
  13. const (
  14. _defaultChannel = "bili"
  15. )
  16. var (
  17. _emptyVersion = []*version.Version{}
  18. _emptyVersionSo = []*version.VersionSo{}
  19. )
  20. // Service version service.
  21. type Service struct {
  22. dao *verdao.Dao
  23. cache map[int8][]*version.Version
  24. upCache map[int8]map[string][]*version.VersionUpdate
  25. uplimitCache map[int][]*version.UpdateLimit
  26. soCache map[string][]*version.VersionSo
  27. increCache map[int8]map[string][]*version.Incremental
  28. rnCache map[string]map[string]*version.Rn
  29. tick time.Duration
  30. }
  31. // New new a version service.
  32. func New(c *conf.Config) (s *Service) {
  33. s = &Service{
  34. dao: verdao.New(c),
  35. tick: time.Duration(c.Tick),
  36. cache: map[int8][]*version.Version{},
  37. upCache: map[int8]map[string][]*version.VersionUpdate{},
  38. uplimitCache: map[int][]*version.UpdateLimit{},
  39. soCache: map[string][]*version.VersionSo{},
  40. increCache: map[int8]map[string][]*version.Incremental{},
  41. rnCache: map[string]map[string]*version.Rn{},
  42. }
  43. s.load()
  44. go s.loadproc()
  45. return
  46. }
  47. // Version return version
  48. func (s *Service) Version(plat int8) (res []*version.Version, err error) {
  49. if res = s.cache[plat]; res == nil {
  50. res = _emptyVersion
  51. }
  52. return
  53. }
  54. // VersionUpdate return version
  55. func (s *Service) VersionUpdate(build int, plat int8, buvid, sdkint, channel, module, oldID string) (res *version.VersionUpdate, err error) {
  56. var (
  57. gvu, tmp []*version.VersionUpdate
  58. )
  59. if vup, ok := s.upCache[plat]; ok {
  60. if tmp, ok = vup[channel]; !ok || len(tmp) == 0 {
  61. if plat == model.PlatAndroidTVYST {
  62. err = ecode.NotModified
  63. return
  64. }
  65. if tmp, ok = vup[_defaultChannel]; !ok || len(tmp) == 0 {
  66. err = ecode.NotModified
  67. return
  68. }
  69. }
  70. for _, t := range tmp {
  71. tu := &version.VersionUpdate{}
  72. *tu = *t
  73. gvu = append(gvu, tu)
  74. }
  75. } else {
  76. err = ecode.NotModified
  77. return
  78. }
  79. LOOP:
  80. for _, vu := range gvu {
  81. if build >= vu.Build {
  82. err = ecode.NotModified
  83. return
  84. }
  85. if vu.IsGray == 1 {
  86. if len(vu.SdkIntList) > 0 {
  87. if _, ok := vu.SdkIntList[sdkint]; !ok {
  88. continue LOOP
  89. }
  90. }
  91. if module != vu.Model && vu.Model != "" {
  92. continue LOOP
  93. }
  94. if buvid != "" {
  95. id := farm.Hash32([]byte(buvid))
  96. n := int(id % 100)
  97. if vu.BuvidStart > n || n > vu.BuvidEnd {
  98. continue LOOP
  99. }
  100. }
  101. }
  102. if limit, ok := s.uplimitCache[vu.Id]; ok {
  103. var tmpl bool
  104. for i, l := range limit {
  105. if i+1 <= len(limit)-1 {
  106. if ((l.Conditions == "gt" && limit[i+1].Conditions == "lt") && (l.BuildLimit < limit[i+1].BuildLimit)) ||
  107. ((l.Conditions == "lt" && limit[i+1].Conditions == "gt") && (l.BuildLimit > limit[i+1].BuildLimit)) {
  108. if (l.Conditions == "gt" && limit[i+1].Conditions == "lt") &&
  109. (build > l.BuildLimit && build < limit[i+1].BuildLimit) {
  110. res = vu
  111. break LOOP
  112. } else if (l.Conditions == "lt" && limit[i+1].Conditions == "gt") &&
  113. (build < l.BuildLimit && build > limit[i+1].BuildLimit) {
  114. res = vu
  115. break LOOP
  116. } else {
  117. tmpl = true
  118. continue
  119. }
  120. }
  121. }
  122. if tmpl {
  123. tmpl = false
  124. continue
  125. }
  126. if model.InvalidBuild(build, l.BuildLimit, l.Conditions) {
  127. continue
  128. } else {
  129. res = vu
  130. break LOOP
  131. }
  132. }
  133. } else {
  134. res = vu
  135. break LOOP
  136. }
  137. }
  138. if res == nil {
  139. err = ecode.NotModified
  140. return
  141. }
  142. res.Incre = s.versionIncrementals(plat, res.Build, oldID)
  143. return
  144. }
  145. // versionIncrementals version incrementals
  146. func (s *Service) versionIncrementals(plat int8, build int, oldID string) (ver *version.Incremental) {
  147. if v, ok := s.increCache[plat]; ok {
  148. if vers, ok := v[oldID]; ok {
  149. for _, value := range vers {
  150. if value.Build == build {
  151. ver = value
  152. return
  153. }
  154. }
  155. }
  156. }
  157. return
  158. }
  159. // VersionSo return version_so
  160. func (s *Service) VersionSo(build, seed, sdkint int, name, model string) (vsdesc *version.VersionSoDesc, err error) {
  161. vSo := s.soCache[name]
  162. if len(vSo) == 0 {
  163. err = ecode.NotModified
  164. return
  165. }
  166. vsdesc = &version.VersionSoDesc{
  167. Package: vSo[0].Package,
  168. Name: vSo[0].Name,
  169. Description: vSo[0].Description,
  170. Clear: vSo[0].Clear,
  171. }
  172. for _, value := range vSo {
  173. if value.Min_build > build || (seed > 0 && seed%100 >= value.Coverage) || (sdkint != value.Sdkint && value.Sdkint != 0) || (model != value.Model && value.Model != "" && value.Model != "*") {
  174. continue
  175. }
  176. vsdesc.Versions = append(vsdesc.Versions, value)
  177. }
  178. if vsdesc.Versions == nil {
  179. vsdesc.Versions = _emptyVersionSo
  180. }
  181. return
  182. }
  183. // VersionRn return version_rn
  184. func (s *Service) VersionRn(version, deploymentKey, bundleID string) (vrn *version.Rn, err error) {
  185. if v, ok := s.rnCache[deploymentKey]; ok {
  186. if vrn, ok = v[version]; !ok {
  187. err = ecode.NotModified
  188. } else if vrn.BundleID == bundleID {
  189. err = ecode.NotModified
  190. }
  191. } else {
  192. err = ecode.NotModified
  193. }
  194. return
  195. }
  196. // load cache data
  197. func (s *Service) load() {
  198. ver, err := s.dao.All(context.TODO())
  199. if err != nil {
  200. log.Error("version s.dao.All() error(%v)", err)
  201. return
  202. }
  203. s.cache = ver
  204. upver, err := s.dao.Updates(context.TODO())
  205. if err != nil {
  206. log.Error("version s.dao.GetUpdate() error(%v)", err)
  207. return
  208. }
  209. s.upCache = upver
  210. log.Info("version cacheproc success")
  211. sover, err := s.dao.Sos(context.TODO())
  212. if err != nil {
  213. log.Error("version s.dao.Sos() error(%v)", err)
  214. return
  215. }
  216. uplimit, err := s.dao.Limits(context.TODO())
  217. if err != nil {
  218. log.Error("version s.dao.Limits() error(%v)", err)
  219. return
  220. }
  221. s.uplimitCache = uplimit
  222. s.soCache = sover
  223. log.Info("versionso cacheproc success")
  224. increver, err := s.dao.Incrementals(context.TODO())
  225. if err != nil {
  226. log.Error("version s.dao.Incrementals error(%v)", err)
  227. return
  228. }
  229. s.increCache = increver
  230. log.Info("versionIncre cacheproc success")
  231. rn, err := s.dao.Rn(context.TODO())
  232. if err != nil {
  233. log.Error("version s.dao.Rn error(%v)", err)
  234. return
  235. }
  236. s.rnCache = rn
  237. log.Info("versionRn cacheproc success")
  238. }
  239. // cacheproc load cache data
  240. func (s *Service) loadproc() {
  241. for {
  242. time.Sleep(s.tick)
  243. s.load()
  244. }
  245. }
  246. // Close dao
  247. func (s *Service) Close() {
  248. s.dao.Close()
  249. }