我的用例如下:我需要向 0...N
订阅者发送 POST 请求,这些订阅者由 targetUrl 表示。我想将 goroutine 的最大数量限制为 100。我的代码(简化)如下:
package main
import (
"fmt"
"log"
"net/http"
"errors"
)
const MAX_CONCURRENT_NOTIFICATIONS = 100
type Subscription struct {
TargetUrl string
}
func notifySubscribers(subs []Subscription) {
log.Println("notifySubscribers")
var buffer = make(chan Subscription, len(subs))
defer close(buffer)
for i := 0; i < MAX_CONCURRENT_NOTIFICATIONS; i++ {
go notifySubscriber(buffer)
}
for i := range subs {
buffer <- subs[i]
}
}
func notifySubscriber(buffer chan Subscription) {
log.Println("notifySubscriber")
for {
select {
case sub := <-buffer:
log.Println("sending notification to " + sub.TargetUrl)
resp, err := failPost()
if err != nil {
log.Println(fmt.Sprintf("failed to notify %s. error: %s", sub.TargetUrl, err.Error()))
} else {
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Println(fmt.Sprintf("%s responded with %d", sub.TargetUrl, resp.StatusCode))
}
}
}
log.Println(fmt.Sprintf("buffer size: %d", len(buffer)))
}
}
func failPost() (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusBadRequest,
}, errors.New("some bad error")
}
func main() {
log.Println("main")
var subs []Subscription
subs = append(subs, Subscription{TargetUrl: "http://foo.bar"})
subs = append(subs, Subscription{TargetUrl: "http://fizz.buzz"})
notifySubscribers(subs)
select {}
}
输出如下:
2018/01/24 10:52:48 通知失败。错误:一些严重的错误
2018/01/24 10:52:48 缓冲区大小:1
2018/01/24 10:52:48 发送通知给
2018/01/24 10:52:48 通知失败。错误:一些严重的错误
2018/01/24 10:52:48 缓冲区大小:0
2018/01/24 10:52:48 发送通知给
2018/01/24 10:52:48 通知失败。错误:一些严重的错误
...等等,直到我 SIGINT 程序
所以基本上这意味着我已经成功地将通知发送给了正确的人,但我仍然继续发送到空的 targetUrl,因为我从一个空的 chan 中读取。
怎么了?
[编辑] 解决方法,但我不喜欢它
for {
select {
case sub, more := <-buffer:
if !more {
return
}
}
}
最佳答案
这是因为您正在关闭缓冲区,但您的 notifySubscriber
仍在监听缓冲区。关闭的 channel 始终返回默认类型值(在本例中为空 Subscription
和空 TargetURL
)。因此,您得到一个空字符串。
场景:
- 如果你想保持 goroutines 运行,那么不要关闭缓冲区。
- 工作完成后停止 goroutine,然后关闭缓冲区。
关于go - 拉 0 大小的 golang chan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48419499/