我关注this answer 使用Akka Streams创建SQS消费者:
def queryForMessages = {
val messages = Sqs.receive(queueUrl, 3, 10)
println(s"Received from sqs: ${messages.map(_.getBody)}")
messages
}
def messageListStream : immutable.Stream[Iterable[SqsMessage]] = {
queryForMessages #:: messageListStream
}
def messageIterator() : Iterator[SqsMessage] = messageListStream.flatten.toIterator
Source.fromIterator(messageIterator)
.map(_.getBody)
.runForeach(m => println(s"Stream output: $m"))(materializer)
除了从队列接收的最后一个元素没有被流拾取之外,这一切似乎都有效。 即如果我将四个项目发布到sqs,则只有3个项目被流打印出来(项目“2”缺失)。我得到的输出是:
Received from sqs: List(1)
Received from sqs: List(3, 4, 2)
Stream output: 1
Stream output: 3
Stream output: 4
Received from sqs: List()
Received from sqs: List()
如果我发布更多元素,实际上会出现缺少的元素(2):
Received from sqs: List(5)
Stream output: 2
Received from sqs: List(6)
Stream output: 5
有什么想法吗?
答案 0 :(得分:0)
正如我在评论部分写的那样,我认为问题的根源在于Streams以及因此懒惰的尾部评估被用作中介。
Stream组件是不必要的,因为单独Iterator
可以解决问题:
val messageListIterator : () => Iterator[Iterable[SqsMessage]] =
() => Iterator continually queryForMessages
val messageIterator : () => Iterator[SqsMessage] =
() => messageListIterator() flatMap identity
现在可以在您的akka流Source
中使用:
Source
.fromIterator(messageIterator)
.map(_.getBody)
.runForeach(m => println(s"Stream output: $m"))(materializer)
我已相应更新了the linked question。