Scala Akka代码提前终止

时间:2015-10-06 21:38:07

标签: scala akka actor

嘿伙计们对scala和akka很新,所以我只是在尝试一下...... 但我不明白为什么我的代码提前终止。它工作但直到最后。 最后一位演员迈克在1000之前终止了。

import akka.actor.{Actor, ActorLogging, Props, ActorSystem}
class Person extends Actor with ActorLogging {
def receive = {
    case FullPint(number) =>
        log.info(s"Comsuming pint $number")
        log.info(s"Consumed pint $number")
        sender ! EmptyPint(number)
    }
}

class BarTender extends Actor with ActorLogging {
    var totalOrders = 0
    var totalEmpty = 0
    def receive = {
        case Ticket(quantity) =>
            totalOrders += quantity
            log.info(s"Serving up $quantity pints to [${sender.path}]")
            for(number <- 1 to quantity) {
                log.info(s"Preparing pint $number for [${sender.path}]")
                log.info(s"Sending pint $number to [${sender.path}]")
                log.info(s"$totalOrders ----- $totalEmpty")
                sender ! FullPint(number)
            }
        case EmptyPint(number) =>
            totalEmpty = totalEmpty + 1
            if(totalEmpty == totalOrders) {
                log.info("Bar is shutting down")
                context.system.shutdown()
            }
    }
}

case class Ticket(quantity:Int)
case class FullPint(number:Int)
case class EmptyPint(number:Int)

object HowdyAkka extends App {
    val system = ActorSystem("howdy")

    val zed = system.actorOf(Props(new BarTender), "zed")

    val alice = system.actorOf(Props(new Person), "alice")
    val bob = system.actorOf(Props(new Person), "bob")
    val mike = system.actorOf(Props(new Person), "mike")

    zed.tell(Ticket(3), alice)
    zed.tell(Ticket(2), bob)
    zed.tell(Ticket(1000), mike)

   system.awaitTermination()
}

1 个答案:

答案 0 :(得分:0)

考虑以下可能的顺序:

  • bartender收到alice的票证(3)
  • 调酒师:totalOrders - &gt; 3,发送给alice的三条FullPint消息
  • alice:按顺序处理3条FullPint消息,返回EmptyPint消息
  • bartender在收到下一张Ticket消息之前收到三条EmptyPint消息
  • bartender:totalEmpty - &gt; 3,= totalOrders:调用shutdown shutdown
  • bartender现在为bob处理下一张Ticket(2),totalOrders - &gt; 5等...

......不久之后,但在迈克处理所有1000品脱之前......

  • shutdown赶上系统,程序结束。

无法保证从不同来源发送的消息将以任何特定顺序到达演员的邮箱,只有单个给定来源的消息才会按顺序到达。因此,Ticket将按顺序到达BarTender的邮箱,但来自EmptyPint的{​​{1}}邮件可能会进入alice在下一个BarTender之前的邮箱,启用上面的序列并混淆您的期望。