Я должен реализовать интерфейс Iterator (как определено Java API), с методами hasNext() и next(), которые должны возвращать элементы результата которые исходят из асинхронно обработанного HTTP-ответа (обрабатываются актерами Akka).Iterate with hasNext() и next() над асинхронно генерируемым потоком элементов
Этих требования должны быть удовлетворено:
- не блокируют и ждать асинхронной операцию, чтобы закончить, как поколение большого набора результатов, может занять некоторое время (итератор должен возвращать результирующие элементы, как только они становятся доступными)
- Iterator.next() должен блокироваться до тех пор, пока не будет доступен следующий элемент (или выбросьте исключение, если больше не будет элементов)
- Iterator.hasNext() должен возвращать true, пока есть больше элементов (даже если следующий пока недоступен)
- Общее количество результатов неизвестно заранее. Агенты, производящие результат, отправят определенное «конечное сообщение», когда оно будет завершено.
- старайтесь избегать использования InterruptedException, например. когда итератор ожидает пустой очереди, но не будет генерироваться больше элементов.
Я еще не изучал потоки Java 8 или потоки Akka. Но поскольку я в основном должен перебирать очередь (конечный поток), я сомневаюсь, что есть какое-то подходящее решение.
В настоящее время моя Scala окурок реализация использует java.util.concurrent.BlockingQueue и выглядит следующим образом:
class ResultStreamIterator extends Iterator[Result] {
val resultQueue = new ArrayBlockingQueue[Option[Result]](100)
def hasNext(): Boolean = ??? // return true if not done yet
def next(): Result = ??? // take() next element if not done yet
case class Result(value: Any) // sent by result producing actor
case object Done // sent by result producing actor when finished
class ResultCollector extends Actor {
def receive = {
case Result(value) => resultQueue.put(Some(value))
case Done => resultQueue.put(None)
}
}
}
Я использую вариант [Результат], чтобы указать конец результирующего потока с None. Я экспериментировал с подглядыванием следующего элемента и использованием флага «done», но я надеюсь, что есть более легкое решение.
Бонус вопросы:
- Как реализация синхронной/асинхронной быть покрыты юнит тестами, особенно тестирования поколение отсроченного результата?
- Как можно сделать итератор потокобезопасным?
Если вы используете Java 8, реализовать 'Spliterator' и' StreamSupport.stream (yourSpliterator, ложь/истина) ' – fge
Собираетесь ли вы использовать Java или Scala? – Bubletan
@Bubletan Я бы предпочел Скала. Но алгоритм не должен иметь большого значения в Java и Scala (кроме синтаксиса). – goerlitz