I run a website that handles large files (uploads and downloads). Currently I am transitioning the site from Perfect to Vapor. In Perfect, it is relatively simple to stream a file to users, and then perform some actions AFTER the file is done.
I am trying to do the same thing in Vapor, but I can't seem to figure out how to set a callback when the stream finished, and when it finished, whether it was completely downloaded by the user or there was an interruption.
Is anyone aware of how to do this? Here are some things that I have tried.
This is the basic structure
func downloadFile(request: Request) -> EventLoopFuture<Response> {
//do some authentication stuff here
let promise = request.eventLoop.makePromise(of: Response.self)
let response = request.fileio.streamFile(at: "somePath")
promise.succeed(response)
let future = promise.futureResult
return future
}
First modification
func downloadFile(request: Request) -> EventLoopFuture<Response> {
//do some authentication stuff here
let promise = request.eventLoop.makePromise(of: Response.self)
let response = request.fileio.streamFile(at: "somePath")
promise.succeed(response)
let future = promise.futureResult
future.eventLoop.next().execute {
//run some post-download processing here.
//ideally I would like to know if the download completed or not.
}
return future
}
Second modification
func downloadFile(request: Request) -> EventLoopFuture<Response> {
//do some authentication stuff here
let promise = request.eventLoop.makePromise(of: Response.self)
let response = request.fileio.streamFile(at: "somePath")
promise.succeed(response)
let future = promise.futureResult
future.whenComplete { result in
switch result {
case .succeed:
//run succeed processing here.
case .failure:
//run failure code here
}
}
return future
}
In all the above cases, what happens is all the processing is done immediately (likely because we're dealing with futures and promises and everything is async).
My question is, is there any way in Vapor to know when a large file has finished streaming and what the result of the stream is? Some middleware maybe?
As of a recent release of Vapor, there is now an optional handler that you can use to preform actions on success / failure of download.
let response = request.fileio.streamFile(at: somepath) { result in
switch result {
case .success(): //do success processing
case .failure(let error): // do failure processing and can print(error)
}
}