利用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
}