Precondition failure when write request body into file asyncronously.
alex1704 opened this issue · 10 comments
Describe the bug
I'm implementing upload functionality with HTTPBodyStreamStrategy == .stream. Inside request handler i'm writing data to file in chunks ayncronously. When large file is uploaded precondition failure is executed.
Here is my implementation:
import Vapor
import NIO
func routes(_ app: Application) throws {
app.on(.POST, "upload", body: .stream, use: { req async throws in
var offset: Int64 = 0
let uploads = req.application.directory.workingDirectory.appending("uploads")
let outPath = "\(uploads)/file"
try? FileManager.default.createDirectory(atPath: uploads, withIntermediateDirectories: false)
try? FileManager.default.removeItem(atPath: outPath)
let fileHandle = try NIOFileHandle(path: outPath, mode: .write, flags: .allowFileCreation())
for try await buffer in req.body {
try await req.application.fileio.write(fileHandle: fileHandle,
toOffset: offset,
buffer: buffer,
eventLoop: req.eventLoop).get()
offset += Int64(buffer.readableBytes)
}
try fileHandle.close()
return "ok"
})
}
To Reproduce
- create large file (600M):
mkfile -n 600m file
curl -X POST 'http://localhost:8080/upload' --data-binary '@file'
- see error
Also i noticed that error appear after repeating curl request several times on smaller files, like 100M.
Expected behavior
No error should happen.
If i use futures implementation, everything works fine.
Environment
- Vapor Framework version: 4.74.1
- Vapor Toolbox version: 18.6.0
- OS version: macOS 13.2 (22D49)
This should now be fixed, feel free to reopen if not!
@0xTim, still can reproduce. I created hello world project with upload
endpoint. Additionally added bigFileTest.sh
script to replicate the issue.
My current environment:
- Vapor:
- framework: 4.86.2
- toolbox: 18.7.4
- OS: 13.6 (22G120)
helloVapor.zip
I can confirm, this bug still exists in Vapor 4.92.1, any ideas how to fix it? 🤔
@tib does the
async-streaming-body-client-disconnect
branch fix it?
Can't find the branch
@hsharghi we've just released https://github.com/vapor/vapor/releases/tag/4.92.3 which has the fix in it
@0xTim The issue still exists
Vapor/RequestBody+Concurrency.swift:34: Fatal error
preconditionFailure() NIO-SGLTN-0-#5 (10): Fatal error
yep, can confirm hsharghi message, bug still persists in 4.92.3 version.