go的线程在实际中的实践?

比如获取游戏信息的接口,除了基本的游戏信息之外一同返回额外的信息:评论,关联的文章,算法推荐。

{
    "game_basic":{

    },
    "game_article":{

    },
    "game_suggestion":{
        
    }
}

每一个都需要涉及对应的数据库查询,以前是线性的查询,一个查完再查另一个。如何使用Goroutine或者通道或者context进行,将额外的信息可以通过Goroutine获取。

  1. 需要对所有的额外设置统一的超时时间
  2. 外部能够取消新开的Goroutine
  3. 查询并不是一个循环执行的操作,本身就是一个耗时操作,怎么取消这个部分
  4. 怎么更好的获取额外的信息,每一个定义一个通道太繁复了

我目前的想法是这样,性能或者内存有影响么。还需要解决不超时更快的情况

func GetGame() {
    gameCh := make(chan interface{})
    ctx, _ := context.WithTimeout(context.Background(), time.Second*1)

    go GetGameArticle(gameCh)
    go GetGameComment(gameCh)

    game := bson.M{}

    for {
        select {
        case extra := <-gameCh:
            game["article"] = extra
        case <-ctx.Done():
            goto DONE
        }
    }
DONE:

    fmt.Println(game)
}

func GetGameArticle(ch chan interface{}) {
    ch <- "666666666666"
}

func GetGameComment(ch chan interface{}) {
    ch <- "99999999999"
}
阅读 1.7k
2 个回答

取消一个没有循环的goroutine没想到好方法。查询数据库时也设置一个超时,避免泄露就好了吧。

第四个问题:GetGameArticle这种获取部分信息的函数里是不是可以直接反序列化game的一部分内容。就不用考虑chan发送出来的字符串应该放在那里了。

如果是考虑db查询超时,你可以考虑在查询的时候加上timeout 的上下文。这样简单明了,也不会出错。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题