从队列消耗好Scala模式,直到没有更多消息?

时间:2018-04-25 16:34:50

标签: scala design-patterns queue akka

我有一个由Actor发送的N个消息队列,我想全部消费它们。如果队列为空,则actor将返回Message类型或NoMessages类型。

我想出了这个,但不觉得惯用,而且我不确定每次拨打consume()时我有多少线程在旋转?

这样做的更好方法是什么?

def main(): Unit = {

  val queue = system.actorOf(...)

  def consume(): Unit = {
    ask(queue, Read) foreach {
      case Message(m) => {
        // handle message
        consume()
      }
      case NoMessages =>  {
        system.shutdown()
      }
    }
  }
  consume()
}

1 个答案:

答案 0 :(得分:5)

如果MessageNoMessages扩展了一个共同特征(让我们称之为Msg),您可以使用Akka Streams

import akka.Done
import akka.actor._
import akka.stream._
import akka.stream.scaladsl._
import akka.util.Timeout
import scala.concurrent._
import scala.concurrent.duration._

implicit val system = ActorSystem("QueueSys")
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher

val queue = system.actorOf(...)

def handleMessage(msg: Message): Unit = ???

implicit val askTimeout = Timeout(5.seconds)

val stream: Future[Done] = Source.fromIterator(() => Iterator.continually(Read))
  .ask[Msg](parallelism = 3)(queue) // adjust the parallelism as needed
  .takeWhile(_.isInstanceOf[Message])
  .runForeach(handleMessage)

stream.onComplete(_ => system.terminate())

以上信息流会不断向Read参与者发送queue条消息并处理Message响应,直到演员回复NoMessage