发送初始Akka消息

时间:2019-12-25 14:59:43

标签: scala akka

在下面的akka​​结构中,我的Parent演员将StartMessage发送给Parent演员,然后将ChildMessage发送给Child演员。收到ChildMessage后,将调用一个运行sh文件的sys进程:"/Users/setup.sh" !!为了确保DoM之后发送StartMessage消息,我插入了一个Thread.sleep:< / p>

parentActor ! StartMessage

Thread.sleep(5000)

parentActor ! DoM

setup.sh执行其他参与者依赖的初始化时,必须首先发送StartMessage。是否有其他机制可以阻止在发送初始消息之前发送消息?

所有代码:

import akka.actor.{Actor, ActorRef, ActorSystem, Props, _}
import akka.stream.ActorMaterializer

import scala.sys.process._

case object ChildMessage
case object ReplyMessage
case object StartMessage
case object StopMessage
case object DoM

class Parent(child: ActorRef) extends Actor {
  var count = 0
  def incrementAndPrint { count += 1; println("incrementing and printing") }
  def receive = {
    case StartMessage =>
      println("Received StartMessage in child")
      incrementAndPrint
      child ! ChildMessage
    case ReplyMessage =>
    case DoM =>
      println("DoM")
    case _ => println("Parent got something unexpected.")
  }
}

class Child extends Actor {
  def receive = {
    case ChildMessage =>
      println("Received Child Message")
      "/Users/setup.sh" !!

      sender ! ReplyMessage
    case StopMessage =>
      println("Received Stop Message")
      context.stop(self)
    case _ => println("Child got something unexpected.")
  }
}

object Question {

  def main(args: Array[String]): Unit = {
    val system = ActorSystem("sys")
    implicit val materializer = ActorMaterializer.create(system)

    val childActor = system.actorOf(Props[Child], name = "RunServerC")
    val parentActor = system.actorOf(Props(new Parent(childActor)), name = "RunServerP")

    parentActor ! StartMessage

    Thread.sleep(5000)

    parentActor ! DoM


  }

}

2 个答案:

答案 0 :(得分:1)

您可以通过调用context.become来更改演员的行为。另外,您可以定义两个新的object,以便在收到意外消息时使用:

object Parent {
  case object NotYetInitialised
  case object AlreadyInitialised
}

class Parent(child: ActorRef) extends Actor {
  def receive = {
    case StartMessage =>
      println("Received StartMessage")
      child ! ChildMessage
      context.become(initialised)
    case _ =>
      println("Parent got something unexpected.")
      sender ! Parent.NotYetInitialised
  }

  def initialised: Receive = {
    case ReplyMessage =>
    case DoM => println("DoM")
    case ResetMessage => context.become(receive) // I made it up
    case StartMessage => sender ! Parent.AlreadyInitialised
    case _   => println("Parent got something unexpected.")
  }
}

答案 1 :(得分:1)

您可以尝试使用Akka ask方法将消息发送给另一个actor,但要记住的一件事是接收方actor必须响应发送方actor。因此,根据您的情况,您可以将Ask用作同步呼叫或异步呼叫。

询问同步

Await.result(parentActor ? StartMessage, 10 seconds)

询问异步

import akka.pattern.ask
import scala.util.{Failure, Success}
import akka.util.Timeout

implicit val timeout = Timeout(10 seconds)
(parentActor ? StartMessage).onComplete{
    case Success(value) =>
    case Failure(exception) => 

}(context.dispatcher)

在子演员中完成工作后,您会通过发送诸如sender() ! "Work is done"之类的消息来回复父演员

相关问题