123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- package relation
- import (
- "context"
- "encoding/json"
- "go-common/library/net/metadata"
- "sort"
- "strconv"
- )
- // Pair ...
- // 自定义map排序结构
- type Pair struct {
- Key int64
- Value int64
- }
- // Gray ...
- // 自定义灰度策略结构
- type Gray struct {
- Key string
- Value int
- }
- // ErrLogStrut ...
- // 自定义ErrLog结构
- type ErrLogStrut struct {
- Code int64
- Msg string
- ErrDesc string
- ErrType string
- URLName string
- RPCTimeout int64
- ChunkSize int64
- ChunkNum int64
- ErrorPtr *error
- }
- // GrayRule ...
- // 自定义灰度策略
- type GrayRule struct {
- Name string `json:"name"`
- Mark string `json:"mark"`
- Value string `json:"value"`
- }
- // PairList ...
- // 自定义灰度策略
- type PairList []Pair
- // GrayList ...
- // 自定义灰度策略
- type GrayList []Gray
- // Swap
- // 自定义排序
- func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
- // Len
- // 自定义排序
- func (p PairList) Len() int { return len(p) }
- // Less
- // 自定义排序
- func (p PairList) Less(i, j int) bool { return p[i].Value > p[j].Value }
- // Swap
- // 自定义排序
- func (p GrayList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
- // Len
- // 自定义排序
- func (p GrayList) Len() int { return len(p) }
- // Less
- // 自定义排序
- func (p GrayList) Less(i, j int) bool { return p[i].Value < p[j].Value }
- // SortMap ...
- // 自定义排序
- func SortMap(input map[int64]int64) (sorted PairList) {
- p := make(PairList, len(input))
- i := 0
- for k, v := range input {
- p[i] = Pair{k, v}
- i++
- }
- sort.Sort(p)
- sorted = p
- return
- }
- const (
- _androidBugBuildLeft = 5332000
- _androidBugBuildRight = 5341000
- )
- // SortMapByValue ...
- // 自定义排序
- func SortMapByValue(m map[string]int) GrayList {
- p := make(GrayList, len(m))
- i := 0
- for k, v := range m {
- p[i] = Gray{k, v}
- i++
- }
- sort.Sort(p)
- return p
- }
- // RParseInt ...
- // 转int
- func RParseInt(inputStr string, defaultValue int64) (output int64) {
- if mid, err := strconv.ParseInt(inputStr, 10, 64); err == nil {
- output = mid
- } else {
- output = defaultValue
- }
- return
- }
- func RoleMap(role int8) (changeType int64) {
- switch role {
- case 0:
- {
- changeType = -1
- }
- case 1, 2:
- {
- changeType = 0
- }
- case 3, 4, 5, 6:
- {
- changeType = 1
- }
- default:
- {
- changeType = -1
- }
- }
- return
- }
- // CheckReturn ...
- // 检查返回
- func CheckReturn(err error, code int64, msg string, urlName string,
- rpcTimeout int64, chunkSize int64, chunkNum int64) (errLog *ErrLogStrut, success bool) {
- errInfo := ErrLogStrut{}
- errInfo.URLName = urlName
- errInfo.RPCTimeout = rpcTimeout
- errInfo.ChunkSize = chunkSize
- errInfo.ChunkNum = chunkNum
- success = true
- if err != nil {
- errInfo.Code = 1003000
- errInfo.Msg = ""
- errInfo.ErrDesc = "liveRpc调用失败"
- errInfo.ErrType = "LiveRpcFrameWorkCallError"
- errInfo.ErrorPtr = &err
- success = false
- } else if code != 0 {
- errInfo.Code = code
- errInfo.Msg = msg
- errInfo.ErrDesc = "调用直播服务" + urlName + "出错"
- errInfo.ErrType = "CallLiveRpcCodeError"
- success = false
- }
- errLog = &errInfo
- return
- }
- // App531ABTest ...
- // ABTest
- func App531ABTest(ctx context.Context, content string, build string, platform string) (grayType int64) {
- buildIntValue := RParseInt(build, 534000)
- if platform == "android" && buildIntValue > _androidBugBuildLeft && buildIntValue <= _androidBugBuildRight {
- grayType = 0
- return
- }
- if len(content) == 0 {
- grayType = 0
- return
- }
- resultMap := make(map[string]int64)
- resultMap["double_small_card"] = 0
- resultMap["card_not_auto_play"] = 1
- resultMap["card_auto_play"] = 2
- typeMap := make([]string, 0)
- mr := &[]GrayRule{}
- if err := json.Unmarshal([]byte(content), mr); err != nil {
- grayType = 0
- return
- }
- ruleArr := *mr
- scoreMap := make(map[string]int)
- for _, v := range ruleArr {
- scoreMap[v.Mark] = int(RParseInt(v.Value, 100))
- }
- sortedScore := SortMapByValue(scoreMap)
- scoreEnd := make([]int, 0)
- for _, v := range sortedScore {
- scoreEnd = append(scoreEnd, v.Value)
- typeMap = append(typeMap, v.Key)
- }
- score1 := scoreEnd[0]
- score2 := scoreEnd[0] + scoreEnd[1]
- score3 := 100
- section1 := make(map[int]bool)
- section2 := make(map[int]bool)
- section3 := make(map[int]bool)
- for section1Loop := 0; section1Loop < score1; section1Loop++ {
- section1[section1Loop] = true
- }
- for sectionLoop2 := score1; sectionLoop2 < score2; sectionLoop2++ {
- section2[sectionLoop2] = true
- }
- for sectionLoop3 := score2; sectionLoop3 < score3; sectionLoop3++ {
- section3[sectionLoop3] = true
- }
- mid := GetUIDFromHeader(ctx)
- result := int(mid % 100)
- if scoreEnd[0] != 0 {
- if _, exist := section1[result]; exist {
- grayType = resultMap[typeMap[0]]
- return
- }
- }
- if scoreEnd[1] != 0 {
- if _, exist := section2[result]; exist {
- grayType = resultMap[typeMap[1]]
- return
- }
- }
- if scoreEnd[2] != 0 {
- if _, exist := section3[result]; exist {
- grayType = resultMap[typeMap[2]]
- return
- }
- }
- grayType = 0
- return
- }
- // GetUIDFromHeader ...
- // 获取uid
- func GetUIDFromHeader(ctx context.Context) (uid int64) {
- midInterface, isUIDSet := metadata.Value(ctx, metadata.Mid).(int64) // 大多使用header里的mid解析, 框架已封装请求的header
- mid := int64(0)
- if isUIDSet {
- mid = midInterface
- }
- uid = mid
- return
- }
|