Arhn - архитектура программирования

Не удается выполнить итерацию Play2 и потоковую передачу перечислителя большого файла

Возможный дубликат:
Потоковое содержимое прокси-сервера Play2 Framework для клиента сохраняет соединение открытым после завершения потоковой передачи

Я передаю 11-мегабайтный файл из веб-службы клиенту. По сути, это сквозной прокси. вот мой код:

def getStreamEnumerator(streamUrl: String, mimeType: String) = {
    Akka.future {
        val dataContent = Enumerator.imperative[Array[Byte]]()

        WS.url(streamUrl).withHeaders("Accept"->mimeType).get { response =>
            Iteratee.fold[Array[Byte], PushEnumerator[Array[Byte]]](dataContent)({
                (pipe, bytes) => {
                    println(bytes.length)
                    pipe.push(bytes)
                    pipe
                }
            })
        }.orTimeout("Oops", 20000L).map {eitherPromiseOrTimeout =>
            println(eitherPromiseOrTimeout)
            dataContent.close()
        }
        dataContent
    }
}

и я называю это:

        getStreamEnumerator(imageUrl, "image/png").map { e =>
            Ok.stream(e).withHeaders(
                "Content-Type"->"image/png",
                "Connection"->"Close"
            )
        }

для медленных сервисов это прекрасно работает, я получаю весь файл. Для быстрых сервисов я получаю только небольшую часть файла (которая, кстати, различается по размеру), а остальная часть изображения обрезается. Если изображение, скажем, 11 МБ, я могу получить только 2 МБ, прежде чем методы .close() убьют поток.

Я ЗНАЮ, что Iteratee получает все данные (я вижу это, когда распечатываю их), но кажется, что вызов .close() в Enumerator запускается слишком рано и отключает перечислитель до того, как interatee сможет заполнить его.

У меня есть несколько вопросов:

  1. это правильный способ сделать прокси? Сначала я сделал это с традиционными потоками ввода-вывода Java, которые работали нормально, но не были идиоматическими или неблокирующими.

  2. ЕСЛИ это разумный способ решить эту проблему, куда должен пойти метод Enumerator.close()? .onRedeem имеет ту же проблему, что и .orTimeout

Спасибо!


Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..