Tools.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package relation
  2. import (
  3. "context"
  4. "encoding/json"
  5. "go-common/library/net/metadata"
  6. "sort"
  7. "strconv"
  8. )
  9. // Pair ...
  10. // 自定义map排序结构
  11. type Pair struct {
  12. Key int64
  13. Value int64
  14. }
  15. // Gray ...
  16. // 自定义灰度策略结构
  17. type Gray struct {
  18. Key string
  19. Value int
  20. }
  21. // ErrLogStrut ...
  22. // 自定义ErrLog结构
  23. type ErrLogStrut struct {
  24. Code int64
  25. Msg string
  26. ErrDesc string
  27. ErrType string
  28. URLName string
  29. RPCTimeout int64
  30. ChunkSize int64
  31. ChunkNum int64
  32. ErrorPtr *error
  33. }
  34. // GrayRule ...
  35. // 自定义灰度策略
  36. type GrayRule struct {
  37. Name string `json:"name"`
  38. Mark string `json:"mark"`
  39. Value string `json:"value"`
  40. }
  41. // PairList ...
  42. // 自定义灰度策略
  43. type PairList []Pair
  44. // GrayList ...
  45. // 自定义灰度策略
  46. type GrayList []Gray
  47. // Swap
  48. // 自定义排序
  49. func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  50. // Len
  51. // 自定义排序
  52. func (p PairList) Len() int { return len(p) }
  53. // Less
  54. // 自定义排序
  55. func (p PairList) Less(i, j int) bool { return p[i].Value > p[j].Value }
  56. // Swap
  57. // 自定义排序
  58. func (p GrayList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  59. // Len
  60. // 自定义排序
  61. func (p GrayList) Len() int { return len(p) }
  62. // Less
  63. // 自定义排序
  64. func (p GrayList) Less(i, j int) bool { return p[i].Value < p[j].Value }
  65. // SortMap ...
  66. // 自定义排序
  67. func SortMap(input map[int64]int64) (sorted PairList) {
  68. p := make(PairList, len(input))
  69. i := 0
  70. for k, v := range input {
  71. p[i] = Pair{k, v}
  72. i++
  73. }
  74. sort.Sort(p)
  75. sorted = p
  76. return
  77. }
  78. const (
  79. _androidBugBuildLeft = 5332000
  80. _androidBugBuildRight = 5341000
  81. )
  82. // SortMapByValue ...
  83. // 自定义排序
  84. func SortMapByValue(m map[string]int) GrayList {
  85. p := make(GrayList, len(m))
  86. i := 0
  87. for k, v := range m {
  88. p[i] = Gray{k, v}
  89. i++
  90. }
  91. sort.Sort(p)
  92. return p
  93. }
  94. // RParseInt ...
  95. // 转int
  96. func RParseInt(inputStr string, defaultValue int64) (output int64) {
  97. if mid, err := strconv.ParseInt(inputStr, 10, 64); err == nil {
  98. output = mid
  99. } else {
  100. output = defaultValue
  101. }
  102. return
  103. }
  104. func RoleMap(role int8) (changeType int64) {
  105. switch role {
  106. case 0:
  107. {
  108. changeType = -1
  109. }
  110. case 1, 2:
  111. {
  112. changeType = 0
  113. }
  114. case 3, 4, 5, 6:
  115. {
  116. changeType = 1
  117. }
  118. default:
  119. {
  120. changeType = -1
  121. }
  122. }
  123. return
  124. }
  125. // CheckReturn ...
  126. // 检查返回
  127. func CheckReturn(err error, code int64, msg string, urlName string,
  128. rpcTimeout int64, chunkSize int64, chunkNum int64) (errLog *ErrLogStrut, success bool) {
  129. errInfo := ErrLogStrut{}
  130. errInfo.URLName = urlName
  131. errInfo.RPCTimeout = rpcTimeout
  132. errInfo.ChunkSize = chunkSize
  133. errInfo.ChunkNum = chunkNum
  134. success = true
  135. if err != nil {
  136. errInfo.Code = 1003000
  137. errInfo.Msg = ""
  138. errInfo.ErrDesc = "liveRpc调用失败"
  139. errInfo.ErrType = "LiveRpcFrameWorkCallError"
  140. errInfo.ErrorPtr = &err
  141. success = false
  142. } else if code != 0 {
  143. errInfo.Code = code
  144. errInfo.Msg = msg
  145. errInfo.ErrDesc = "调用直播服务" + urlName + "出错"
  146. errInfo.ErrType = "CallLiveRpcCodeError"
  147. success = false
  148. }
  149. errLog = &errInfo
  150. return
  151. }
  152. // App531ABTest ...
  153. // ABTest
  154. func App531ABTest(ctx context.Context, content string, build string, platform string) (grayType int64) {
  155. buildIntValue := RParseInt(build, 534000)
  156. if platform == "android" && buildIntValue > _androidBugBuildLeft && buildIntValue <= _androidBugBuildRight {
  157. grayType = 0
  158. return
  159. }
  160. if len(content) == 0 {
  161. grayType = 0
  162. return
  163. }
  164. resultMap := make(map[string]int64)
  165. resultMap["double_small_card"] = 0
  166. resultMap["card_not_auto_play"] = 1
  167. resultMap["card_auto_play"] = 2
  168. typeMap := make([]string, 0)
  169. mr := &[]GrayRule{}
  170. if err := json.Unmarshal([]byte(content), mr); err != nil {
  171. grayType = 0
  172. return
  173. }
  174. ruleArr := *mr
  175. scoreMap := make(map[string]int)
  176. for _, v := range ruleArr {
  177. scoreMap[v.Mark] = int(RParseInt(v.Value, 100))
  178. }
  179. sortedScore := SortMapByValue(scoreMap)
  180. scoreEnd := make([]int, 0)
  181. for _, v := range sortedScore {
  182. scoreEnd = append(scoreEnd, v.Value)
  183. typeMap = append(typeMap, v.Key)
  184. }
  185. score1 := scoreEnd[0]
  186. score2 := scoreEnd[0] + scoreEnd[1]
  187. score3 := 100
  188. section1 := make(map[int]bool)
  189. section2 := make(map[int]bool)
  190. section3 := make(map[int]bool)
  191. for section1Loop := 0; section1Loop < score1; section1Loop++ {
  192. section1[section1Loop] = true
  193. }
  194. for sectionLoop2 := score1; sectionLoop2 < score2; sectionLoop2++ {
  195. section2[sectionLoop2] = true
  196. }
  197. for sectionLoop3 := score2; sectionLoop3 < score3; sectionLoop3++ {
  198. section3[sectionLoop3] = true
  199. }
  200. mid := GetUIDFromHeader(ctx)
  201. result := int(mid % 100)
  202. if scoreEnd[0] != 0 {
  203. if _, exist := section1[result]; exist {
  204. grayType = resultMap[typeMap[0]]
  205. return
  206. }
  207. }
  208. if scoreEnd[1] != 0 {
  209. if _, exist := section2[result]; exist {
  210. grayType = resultMap[typeMap[1]]
  211. return
  212. }
  213. }
  214. if scoreEnd[2] != 0 {
  215. if _, exist := section3[result]; exist {
  216. grayType = resultMap[typeMap[2]]
  217. return
  218. }
  219. }
  220. grayType = 0
  221. return
  222. }
  223. // GetUIDFromHeader ...
  224. // 获取uid
  225. func GetUIDFromHeader(ctx context.Context) (uid int64) {
  226. midInterface, isUIDSet := metadata.Value(ctx, metadata.Mid).(int64) // 大多使用header里的mid解析, 框架已封装请求的header
  227. mid := int64(0)
  228. if isUIDSet {
  229. mid = midInterface
  230. }
  231. uid = mid
  232. return
  233. }