1 回答
TA贡献1866条经验 获得超5个赞
OP 代码中的问题是 http.Post 调用从不检测所提供的 io.Reader 的 EOF。
发生这种情况是因为提供的半写管道永远不会关闭,因此,半读管道永远不会发出常规的 EOF 错误。
作为关于关闭半读管道会产生不规则错误的 OP 评论的注释,必须了解从关闭的管道读取不是正确的行为。
因此在这种情况下,应注意在复制完内容后立即关闭半写侧。
生成的源代码应更改为
func ImportAggregate(c echo.Context) error {
oneR, oneW := io.Pipe()
twoR, twoW := io.Pipe()
done := make(chan bool, 2)
go func() {
fmt.Println("Product Starting")
response, err := http.Post("http://localhost:1323/products/import", "application/json", oneR)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(response.Body)
}
done <- true
}()
go func() {
fmt.Println("Import Starting")
response, err := http.Post("http://localhost:1323/discounts/import", "application/json", twoR)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(response.Body)
}
done <- true
}()
mw := io.MultiWriter(oneW, twoW)
io.Copy(mw, c.Request().Body)
oneW.Close()
twoW.Close()
<-done
<-done
return c.String(200, "Imported")
}
OP 问题之外的旁注:
必须围绕 io.Copy 实施错误检查以检测传输错误。
不需要关闭管道的半读端,http.Post 将在收到 EOF 信号后执行此操作。
必须在复制输入请求之前声明并启动负责使用管道的 goroutine。Pipes 是同步的,代码会在 io.Copy 等待另一端被消耗的过程中阻塞。
done chan 不需要无缓冲(长度为 2)
一种将错误从传出请求转发到传出响应的方法是使用 type 的通道
(chan error)
,循环两次,并检查遇到的第一个错误。
- 1 回答
- 0 关注
- 81 浏览
添加回答
举报