1 回答
TA贡献1784条经验 获得超9个赞
我的建议是,使CH缓冲通道,每个查询一个空间:ch := make(chan Result, len(conns))。这样每个查询都可以运行完成,并且不会阻塞通道写入。
Query可以读取一次并返回第一个结果。当所有其他 goroutine 完成时,通道最终将被垃圾回收,一切都会消失。使用无缓冲通道,您可以创建许多永远不会终止的 goroutine。
编辑:如果你想取消飞行中的请求,它会变得更加困难。某些操作和 API 提供取消功能,而其他操作和 API 则不提供。对于 http 请求,您可以Cancel在请求结构上使用字段。只需提供一个您可以关闭以取消的频道:
func (c *Conn) DoQuery(params string, cancel chan struct{}) Result {
//error handling omitted. It is important to handle errors properly.
req, _ := http.NewRequest(...)
req.Cancel = cancel
resp, _ := http.DefaultClient.Do(req)
//On Cancellation, the request will return an error of some kind.
return readData(resp)
}
func Query(conns []Conn, query string) Result {
ch := make(chan Result)
cancel := make(chan struct{})
for _, conn := range conns {
go func(c Conn) {
ch <- c.DoQuery(query,cancel)
}(conn)
}
first := <-ch
close(cancel)
return first
}
如果有一个您不关心的大型读取请求,这可能会有所帮助,但它实际上可能会或可能不会取消远程服务器上的请求。如果您的查询不是 http,而是数据库调用或其他什么,您将需要查看是否有类似的取消机制可以使用。
- 1 回答
- 0 关注
- 171 浏览
添加回答
举报