Akka Streams:缺少源

时间:2017-05-31 16:41:41

标签: scala akka-stream

我关注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

有什么想法吗?

1 个答案:

答案 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