在下面的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
}
}
答案 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"
之类的消息来回复父演员