我使用io.MultiWriter和频道在使用阅读器的不同例程之间进行通信时遇到了一些问题。我正在尝试构建一个上传函数,它接收一个JSON,将其写入磁盘,但同时检查它的mime类型并创建一个缩略图。所以
getUploadData(...)
从JSON中抓取mime字符串并将其写入mimeChan通道,然后由
接收makeAndSaveTbn(...)
然后根据mime制作不同的缩略图。
同时
saveOnDisk(...)
只需将文件保存到磁盘即可。由于我正在流式传输三个例程,因此我将io.Pipes与io.MultiWriter一起使用。
现在问题只是makeAndSaveTbn(...)从未从通道mimeChan接收消息并阻止该程序。写入通道的工作原理,如果我删除对mimeChan的依赖并在ProcessUpload(...)中接收它就可以了。
在某种意义上,io.Writers是否存在问题,实际上它们不能异步读取?
非常感谢任何想法,感谢您已经阅读过此票价!
我的进程上传功能如下所示:
func ProcessUpload(r *File) (err error) {
sr, sw := io.Pipe()
tr, tw := io.Pipe()
pr, pw := io.Pipe()
mimeChan := make(chan string, 1)
done := make(chan string)
defer close(done)
defer close(mimeChan)
go getUploadData(pr, mimeChan, done)
go saveOnDisk(sr, done)
go makeAndSaveTbn(tr, FileID, mimeChan, done)
go func() {
defer sw.Close()
defer tw.Close()
defer pw.Close()
mw := io.MultiWriter(pw, tw, sw)
_, err := io.Copy(mw, r)
if err != nil {
log.Error(err)
}
}()
for c := 0; c < 3; c++ {
log.Errorf(<-done)
}
return err
}
mime检查器看起来像这样:
func getUploadData(pr *io.PipeReader, mimeChan chan string, done chan string) {
var p uploadParams
err := json.NewDecoder(pr).Decode(&p)
if err != nil {
log.Error(err)
}
log.Errorf(p.Mime)
done <- "getUploadData"
mimeChan <- p.Mime
}
这样的阻塞函数,它接收if string中的通道.Contains ...:
func makeAndSaveTbn(tr *io.PipeReader, FileID string, mimeChan chan string, done chan string) {
if strings.ContainsAny(<-mimeChan, "image") {
tbn, err := MakeThumbnail(tr)
if err != nil {
log.Error(err)
}
done <- "makeAndSaveTbn"
}
}