I have the following driver/main class encapsulating my Akka program:
// Groovy pseudo-code
class FizzBuzz {
ActorSystem actorSystem
static void main(String[] args) {
FizzBuzz d = new FizzBuzz()
d.run()
}
void run() {
Initialize initCmd = new Initialize()
MasterActor master = actorSystem.get(...)
// Tells the entire actor system to initialize itself and start doing stuff.
// ChickenCluckDetector is an actor managed/supervised by MasterActor.
master.tell(initCmd, ...)
}
// Called when a ChickenCluckDetector actor inside the actor system receives
// a 'Cluck' message.
void onChickenGoesCluck(Cluck cluck) {
// Do something
}
}
And the following ChickenCluckDetector
actor:
class ChickenCluckDetector extends UntypedActor {
@Override
void onReceive(Object message) {
if(message instanceof Cluck) {
Cluck cluck = message as Cluck
// Now, how to pass the message safely/properly to FizzBuzz#onCluck?
}
}
}
So the problem at hand is how to safely/properly pass the Cluck
message to FizzBuzz#onCluck(Cluck)
, which lives outside the actor system? I could provide a FizzBuzz
reference to ChickenCluckDetector
like so:
class ChickenCluckDetector extends UntypedActor {
FizzBuzz fizzBuzz
@Override
void onReceive(Object message) {
if(message instanceof Cluck) {
Cluck cluck = message as Cluck
fizzBuzz.onCluck(cluck)
}
}
}
But I have a feeling this violates Akka's best practices and could cause all sort of concurrency-based problems, especially if there's only one FizzBuzz
(which there is) non-actor/driver, and ten thousand ChickenCluckDetector
actors. Ideas?
if there's only one FizzBuzz (which there is) non-actor/driver, and ten thousand ChickenCluckDetector actors
Then it would be best to create one common parent for all of these ChickenCluckDetectors. This parent could then safely hold the reference to FizzBuzz, receive clucks from all his children and call the onCluck method.
One option for getting messages outside of actors is asking. And in Scala there is actor DSL (added just for completeness). But I believe you need neither of these in your example.
public class ChickenCluckMaster extends UntypedActor {
private FizzBuzz fizzBuzz;
public ChickenCluckMaster(FizzBuzz fizzBuzz) {
this.fizzBuzz = fizzBuzz;
}
public void onReceive(Object message) throws Exception {
if (message instanceOf CreateDetector) {
getContext().actorOf(
Props.create(ChickenCluckDetector.class, getSelf); // Create child
} else if (message instanceof Cluck) {
fizzBuzz.onCluck(cluck);
} else {
unhandled(message);
}
}
}
public class ChickenCluckDetector extends UntypedActor {
private ActorRef master;
public ChickenCluckDetector(ActorRef master) {
this.master = master;
}
public void onReceive(Object message) throws Exception {
if (message instanceof Cluck) {
Cluck cluck = (Cluck) message;
master.tell(cluck, getSelf);
} else {
unhandled(message);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With