如何解决HTTP API 在写入文件时停止响应
我使用 Gorilla Mux 在 Go 中编写了一个 API http 服务器。它运作良好。其中一个端点用于上传文件并将它们保存到挂载到服务器 pod 的 NFS 共享。客户端是一个使用 Alamofire 的 Swift 5 应用。
对于较小的文件,我们只使用 copy 从请求正文中写入它们。对于较大的文件,我们使用缓冲流读取器和写入器来执行写入,因为我们在仅使用复制时遇到超时和丢失问题。
然而,当写入发生时,服务器停止响应所有新请求。如何更改或优化此代码,以便服务器继续按预期响应?在此处查看代码:
func uploadFile(w http.ResponseWriter,r *http.Request) {
vars := mux.Vars(r)
repoBase := "./repo/gkp-directory/"
folderName := vars["uploadFolder"]
fileName := vars["uploadFile"]
fileSize := r.ContentLength
//
// Check if we have a package. They can be large and require special handling
//
if folderName == "pkgs" {
defer r.Body.Close()
//
// If the content is more than 10MB write to temp cache then move it
// in a seperate goroutine to the repo storage
//
if r.ContentLength > 10000000 {
buf := make([]byte,10000000)
tempFile,err := os.Create(repoBase + folderName + "/" + fileName)
if err != nil {
log.Println("ERROR: Failed to create file.")
log.Println(err.Error())
return
}
defer tempFile.Close()
for {
n,err := r.Body.Read(buf)
if err != nil && err != io.EOF {
log.Println("ERROR: Error creating file on NFS")
log.Println(err.Error())
return
}
if n == 0 {
break
}
if _,err := tempFile.Write(buf[:n]); err != nil {
log.Println("ERROR: Error streaming to NFS")
log.Println(err.Error())
return
}
}
tempFile.Close()
r.Body.Close()
} else {
//
// If the package is smaller than 10MB we should be safe to write it directly to
// the NFS backend with no buffer
//
outputFile,err := os.Create(repoBase + folderName + "/" + fileName)
if err != nil {
log.Println("ERROR: Failed to create file.")
log.Println(err.Error())
return
}
defer outputFile.Close()
written,err := io.copy(outputFile,r.Body)
if err != nil {
log.Println("ERROR: Failed to create file.")
log.Println(err.Error())
return
}
if written == fileSize {
outputFile.Close()
r.Body.Close()
}
}
} else {
//
// Otherwise file is not a package. This means it is just a small text file we
// should safetly be able to write this to NFS with no issues or buffer
//
outputFile,err := os.Create(repoBase + folderName + fileName)
if err != nil {
log.Println("ERROR: Failed to create file.")
log.Println(err.Error())
return
}
defer outputFile.Close()
written,r.Body)
if err != nil {
log.Println("ERROR: Failed to create file.")
log.Println(err.Error())
return
}
if written == fileSize {
outputFile.Close()
r.Body.Close()
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。