利用channel并发从数据库获取多个数据

2020-04-03  本文已影响0人  yellowone

我们在获取用户信息的时候,经常是需要从多个数据源中获取数据,比如获取用户的余额,用户状态,用户拥有物品时,需要拉取多个数据库,如果顺序执行的话,速度不够快,这里分享一种写法。

type dataChan struct {
    data interface{}
    err  error
}

func getMysqlDataByUin(uin int, getDataFunc func(int) (interface{}, error), context context.Context) chan *dataChan {
   result := make(chan *dataChan, 1)
   go func() {
      dataInfo, err := getDataFunc(uin)
      select {
      case <-context.Done():
         close(result)
      default:
         result <- &dataChan{
            data: dataInfo,
            err:  err,
         }
      }
   }()
   return result
}

将获取数据的chan作为结果返回并且并发调用获取数据方法来获取数据

func GatPlayerData(uin int) (*PlayerSaveData, error) {
    ctx, cancel := context.WithCancel(context.Background())
    chanCount := 0
    goldChan := getMysqlDataByUin(uin, readMysql.GetUserGoldInfo, ctx)
    chanCount++
    buffChan := getMysqlDataByUin(uin, readMysql.GetBuffInfo, ctx)
    chanCount++
    resultData := &PlayerSaveData{}
    for i := 0; i < chanCount; i++ {
        select {
        case goldData := <-goldChan:
            if goldData.err != nil {
                cancel()
                return nil, errors.WithMessage(goldData.err, "获取金币信息失败")
            }
            goldInfo, ok := goldData.data.([]*MysqlGoldCoin)
            if !ok {
                cancel()
                return nil, errors.New("类转化失败")
            }
            resultData.MyMoney = goldInfo
        case buffData := <-buffChan:
            if buffData.err != nil {
                cancel()
                return nil, errors.WithMessage(buffData.err, "获取buff信息失败")
            }
            info, ok := buffData.data.([]*MysqlBuff)
            if !ok {
                cancel()
                return nil, errors.New("类转化失败")
            }
            resultData.Buffs = info
        }
    }
    return resultData, nil
}
上一篇下一篇

猜你喜欢

热点阅读