我有一个akka模型,有一个主管演员创建许多儿童演员。儿童演员将处理事件并将消息发送到另一个服务(例如Kafka主题)。
目前,我有一个静态的共享类,该课程是在儿童演员中共享的,用于发送消息,但是在Actor模型中,我认为最好将演员用于此目的。
我想知道如何创建一个儿童演员可以分享的演员。如果主管演员创建了MessagePublisher演员,孩子们可以找到发送消息吗?
谢谢
取决于用例,您可以在最高级别或为您的主管创建共享的Actor
或作为子Actor
。然后,您只需使用消息或构造函数将ActorRef
传递给主管/儿童演员,并将其保留为Actor
内部状态。
以下代码应该说明它(它是Scala,但将其翻译成Java应该很容易)。
package test
import akka.actor.Actor.Receive
import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.stream.ActorMaterializer
object TestClass extends App {
implicit val system = ActorSystem( "ActorSystem" )
implicit val executor = system.dispatcher
implicit val materializer = ActorMaterializer( )
//Option 1 Create as top level actor and pass to supervisor with init message
val sharedActor: ActorRef = system.actorOf( Props[ SharedActor ] )
val supervisor: ActorRef = system.actorOf( Props[ SupervisorActor ] )
supervisor ! InitWithSharedActor( sharedActor )
supervisor ! "NoArgsChild"
supervisor ! "ArgsChild"
class SupervisorActor extends Actor {
private var sharedActor: Option[ ActorRef ] = None
override def preStart( ) = {
//Option 2 Init as child actor of supervisor
println( "Start Supervisor" )
sharedActor = Some( context.actorOf( Props[ SharedActor ] ) )
}
override def receive: Receive = {
case InitWithSharedActor( sa ) =>
sharedActor = Some( sa )
case "NoArgsChild" =>
//Pass to child actor in init msg
sharedActor.foreach( sa => context.actorOf( Props[ ChildActor ] ) ! InitWithSharedActor( sa ) )
case "ArgsChild" =>
//Pass to child with constructor
sharedActor.foreach( sa => context.actorOf( Props( new ChildActorWithArgs( sa ) ) ) )
}
}
class SharedActor extends Actor {
override def preStart( ) = {
println( "Start Shared Actor" )
}
override def receive: Receive = {
case _ =>
}
}
class ChildActor extends Actor {
private var sharedActor: Option[ ActorRef ] = None
override def preStart( ) = {
println( "Start NoArg Child Actor" )
}
override def receive: Receive = {
case InitWithSharedActor( sa ) => sharedActor = Some( sa )
}
}
class ChildActorWithArgs( sharedActor: ActorRef ) extends Actor {
override def preStart( ) = {
println( "Start WithArg Child Actor" )
}
override def receive: Receive = {
case _ =>
}
}
case class InitWithSharedActor( sharedActor: ActorRef )
}