【发布时间】:2018-02-09 19:38:26
【问题描述】:
我的 akka-http 服务器中有以下路由:
def tempDestination(fileInfo: FileInfo): File = {
log.info(s"File info for upload: [$fileInfo]")
File.createTempFile(fileInfo.fileName, ".tmp")
}
...
post {
log.info("Inside the file upload path")
fileUpload("zip") {
case (fileInfo, bytes) =>
val dest = tempDestination(fileInfo)
val uploadedF: Future[(FileInfo, File)] =
bytes
.runWith(FileIO.toPath(dest.toPath))
.map(_ => (fileInfo, dest))
onSuccess(uploadedF) { (info, file) =>
val fileCreated: Future[MyFile] = (fileRegistryActor ? NewFile(file)).mapTo[MyFile]
complete((StatusCodes.Created, fileCreated))
}
}
}
通过表单将文件上传到这里后,我在日志中看到了这一点:
Sending an 2xx 'early' response before end of request was received... Note that the connection will be closed after this response. Also, many clients will not read early responses! Consider only issuing this response after the request data has been completely read!
我认为uploadedF Future 在创建并完成 Sink 的 IOResult 之前不会完成。我错过了什么?确定我的整个请求是否已被读取并且我的文件是否已完全写入磁盘的正确机制是什么?
【问题讨论】:
-
嗯,你可能有太多的未来,试试 runWith().flatmap()
-
在底部的 fileCreated 也是一个未来,所以你可能想要映射它(就像你使用uploadedF 一样)以便调用完成
-
如果我
runWith().flatMap(),那么我的身体需要返回一个Future[(FileInfo, File)],而不仅仅是我拥有的(FileInfo, File)。我可以尝试映射fileCreated未来,但通过查看预制模板,使用 Future 调用complete()是可行的,并且在解决 Future 后完成。 -
另外,如果我映射到
fileCreated,那么我需要专门等待未来,因为 onSuccess 的返回需要是Route而不是Future[Route] -
到目前为止,
onSuccess的主体只被一个成功的IOResult调用。我认为问题是文件在请求完成之前被写入磁盘,我只是在等待文件,而不是请求。