#scala #amazon-s3 #netty #nio
#скала #amazon-s3 #нетти #нио
Вопрос:
ниже приведен код, когда пользователь загружает видео из мобильного приложения в S3
def uploadVideo = Action(parse.multipartFormData) { implicit request =>
try {
var height = 0
var width = 0
request.body.files.map { mov =>
var videoName = System.currentTimeMillis() ".mpeg"
amazonS3Client.putObject(bucketVideos, videoName, mov.ref.file)
}
val map = Map("result" -> "success")
Ok(write(map))
} catch {
case e: Exception =>
Ok(write(Map("result" -> "error")))
}
}
приведенный выше код работает нормально, но в случае отмены пользователем загрузки видео возникает ошибка
[error] play - Exception caught in RequestBodyHandler
java.nio.channels.ClosedChannelException: null
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:434) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:129) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:36) ~[netty.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:725) ~[netty.jar:na]
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.doEncode(OneToOneEncoder.java:71) ~[netty.jar:na]
и это не идет на то, чтобы поймать блока!!
1. может ли это нанести вред серверу или нет?(потому что в случае возникновения ошибки не требуется никакого ответа)
2. если да, как обработать?
Ответ №1:
Все это происходит во внутренних компонентах Play, которые обрабатывают синтаксический анализ тела Request
. Фактически, во время загрузки на ваш сервер вы еще даже не достигли try
блока, потому что загрузка файла не завершена. Только после завершения загрузки у вас есть TemporaryFile
доступное.
Так что нет, вы не можете поймать эту ошибку, да и зачем вам это нужно? Пользователь закрыл соединение. Они даже не ждут ответа, так зачем же его посылать? Пусть Игра справится с этим.
Однако это также не очень хороший способ обработки загрузки. Для небольших файлов это приемлемо, но если кто-то проксирует огромную загрузку видео через ваш сервер на S3, это приведет к:
- Для обработки ответа потребуется почти в два раза больше времени (что приведет к зависанию пользователя во время загрузки на S3).
- Заблокируйте один из потоков Play для обработки запросов на все время, пока файл загружается в S3, и, учитывая достаточное количество таких загрузок (совсем немного), вы больше не сможете обрабатывать запросы до завершения загрузки.
Подумайте, по крайней мере, о создании отдельного ExecutionContext для использования для обработки загрузок, или, что еще лучше, рассмотрите возможность загрузки пользователя непосредственно в S3 через подписанную форму, что вообще избавило бы от необходимости прокси-загрузки.
Комментарии:
1. я отправляю аналогичный вопрос для проверки, пожалуйста, просмотрите его codereview.stackexchange.com/questions/55544 /…