チャンネルを使用してゴルーチンのグループからエラーをキャッチしようとしていますが、チャンネルが無限ループに入り、CPUを使い始めます。チャンネルの無限ループに移動
func UnzipFile(f *bytes.Buffer, location string) error {
zipReader, err := zip.NewReader(bytes.NewReader(f.Bytes()), int64(f.Len()))
if err != nil {
return err
}
if err := os.MkdirAll(location, os.ModePerm); err != nil {
return err
}
errorChannel := make(chan error)
errorList := []error{}
go errorChannelWatch(errorChannel, errorList)
fileWaitGroup := &sync.WaitGroup{}
for _, file := range zipReader.File {
fileWaitGroup.Add(1)
go writeZipFileToLocal(file, location, errorChannel, fileWaitGroup)
}
fileWaitGroup.Wait()
close(errorChannel)
log.Println(errorList)
return nil
}
func errorChannelWatch(ch chan error, list []error) {
for {
select {
case err := <- ch:
list = append(list, err)
}
}
}
func writeZipFileToLocal(file *zip.File, location string, ch chan error, wg *sync.WaitGroup) {
defer wg.Done()
zipFilehandle, err := file.Open()
if err != nil {
ch <- err
return
}
defer zipFilehandle.Close()
if file.FileInfo().IsDir() {
if err := os.MkdirAll(filepath.Join(location, file.Name), os.ModePerm); err != nil {
ch <- err
}
return
}
localFileHandle, err := os.OpenFile(filepath.Join(location, file.Name), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
ch <- err
return
}
defer localFileHandle.Close()
if _, err := io.Copy(localFileHandle, zipFilehandle); err != nil {
ch <- err
return
}
ch <- fmt.Errorf("Test error")
}
私はスライスにそのエラーを保存するために戻ってerrorChannel
に報告し、エラーがあった場合だから私は、ファイルのスライスをループして、私のディスクに書いています。
私はすべてのゴルーチンを待つのにsync.WaitGroup
を使用し、完了したらerrorList
を印刷し、実行中にエラーがないかどうかをチェックします。
writeZipFileToLocal
の末尾にch <- fmt.Errorf("test")
を追加しても、リストは常に空です。チャンネルは常にハングアップします。
私はここで何が欠けているのか分かりません。第一の点について