0
votes

I have a AKKA model that there is a Supervisor actor which creates many child actors. child actors will process an event and send the message to another service (e.g Kafka topic).

Currently I have a static shared class that is shared among child actors for sending out messages, but in Actor model I think it is better to use an actor for this purpose.

I want to know how can I create an actor that child actors can share it. If supervisor actor creates MessagePublisher actor, can children find an send the message to it?

Thank you

1

1 Answers

0
votes

Depending on the use case you can either create the shared Actor at top level or as a child Actor to your supervisor. Then you just pass the ActorRef either using a message or the constructor to the supervisor / child actors and keep it as Actor internal state.

The following code should illustrate it (It's Scala but it should be pretty easy to translate it to 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 )

}