Akka ::在ActorSystem中使用具有不同优先级的消息而不是事件流

时间:2012-08-30 20:24:56

标签: actor akka publish-subscribe priority-queue

我需要将不同类型的消息发布到事件流和那些 消息应该具有不同的优先级,例如,如果10个类型的消息 已经发布了A,毕竟发布了一条B类消息,并且 B的优先级高于A的优先级 - 应该拾取消息B. 即使队列中有10条A类消息,也可以通过下一个演员。

我已阅读有关优先邮件here的信息,并创建了该邮箱的简单实现:

  class PrioritizedMailbox(settings: Settings, cfg: Config) extends UnboundedPriorityMailbox(

    PriorityGenerator {
      case ServerPermanentlyDead => println("Priority:0"); 0
      case ServerDead => println("Priority:1"); 1
      case _ => println("Default priority"); 10
    }

  )

然后我在application.conf

中配置了它
akka {

    actor {

        prio-dispatcher {
            type = "Dispatcher"
            mailbox-type = "mailbox.PrioritizedMailbox"
        }

    }

}

并连接到我的演员:

private val myActor = actors.actorOf(
  Props[MyEventHandler[T]].
    withRouter(RoundRobinRouter(HIVE)).
    withDispatcher("akka.actor.prio-dispatcher").
    withCreator(
    new Creator[Actor] {
      def create() = new MyEventHandler(storage)
    }), name = "eventHandler")

我使用ActorSystem.eventStream.publish发送消息,我的演员 是订阅它(我可以在日志中看到消息被处理,但在 FIFO订单)。

然而看起来还不够,因为在日志/控制台中我从未见过 消息如"默认优先级"。我在这里错过了什么吗?是吗? 描述的方法使用事件流或只是直接调用 在演员身上发送消息?我如何获得优先级消息 eventStream?

1 个答案:

答案 0 :(得分:10)

您的问题是您的演员非常快,所以在他们有时间排队之前处理消息,因此邮箱不能进行任何优先处理。下面的例子证明了这一点:

  trait Foo 
  case object X extends Foo 
  case object Y extends Foo 
  case object Z extends Foo 

  class PrioritizedMailbox(settings: ActorSystem.Settings, cfg: Config) 
extends UnboundedPriorityMailbox( 
    PriorityGenerator { 
      case X ⇒ 0 
      case Y ⇒ 1 
      case Z ⇒ 2 
      case _ ⇒ 10 
    }) 

val s = ActorSystem("prio", com.typesafe.config.ConfigFactory.parseString( 
        """ prio-dispatcher { 
        type = "Dispatcher" 
          mailbox-type = "%s" 
        }""".format(classOf[PrioritizedMailbox].getName))) 
      val latch = new java.util.concurrent.CountDownLatch(1) 
      val a = s.actorOf(Props(new akka.actor.Actor { 
        latch.await // Just wait here so that the messages are queued up 
inside the mailbox 
        def receive = { 
          case any ⇒ /*println("Processing: " + any);*/ sender ! any 
        } 
      }).withDispatcher("prio-dispatcher")) 
      implicit val sender = testActor 
      a ! "pig" 
      a ! Y 
      a ! Z 
      a ! Y 
      a ! X 
      a ! Z 
      a ! X 
      a ! "dog" 

      latch.countDown() 

      Seq(X, X, Y, Y, Z, Z, "pig", "dog") foreach { x => expectMsg(x) } 
      s.shutdown() 

此测试以绚丽的色彩传递