I need the ActorSystem<SpawnProtocol.Command>
in another actor. I would like the GuardianActor to have a reference to ActorSystem<SpawnProtocol.Command>
so I can pass this reference when I spawn the actor using the Guardian Actor, is there any way to do this? I don't see it is possible since we only get ActorSystem<SpawnProtocol.Command>
after creating the actor system and guardian.
ActorSystem<SpawnProtocol.Command> system = ActorSystem.create(GuardianActor.create(), "System", config)
The only option I see is doing something like
system.tell(new SpawnProtocol.Spawn<>(NewActor.create(system)), "NewActor", Props.empty(), system.ignoreRef());
in this case I will not be spawning NewActor
using the guardian actor - which I think is not a clean implementation (correct me if I am wrong)
If I'm understanding you, you want to spawn actors with a reference to the ActorSystem
.
Every actor can obtain a reference to its ActorSystem
via its ActorContext
; the ActorContext
is typically injected by using Behaviors.setup
. You would obtain the ActorSystem
by calling getSystem()
on the ActorContext
. Note that it is an ActorSystem<Void>
, but since the only way it really uses its type parameter is when you're using it as an ActorRef
, the unsafeUpcast()
method can be used. Note that unsafeUpcast
doesn't in any way validate that the cast is valid, but since there will typically not be confusion around the type (there being only one ActorSystem
in a typical application) this normally isn't a problem; if an improper cast is made, it will result in the system crashing when a message is sent.
// Apologies, my Java is pretty rusty
public class Actor1 extends AbstractBehavior<Actor1.Command> {
public static Behavior<Command> create(int x) {
return Behaviors.setup(context -> new Actor1(context, x));
}
private int x;
private final ActorRef<SpawnProtocol.Command> systemGuardian;
private Actor1(ActorContext<Command> context, int x) {
super(context);
this.x = x;
// If doing an unsafeUpcast on the ActorSystem and there's a message
// which will do nothing in its protocol, it might be a good idea to
// send that message eagerly, so everything crashes quickly...
systemGuardian = context.getSystem().unsafeUpcast<SpawnProtocol.Command>()
}
}
When an Actor1
wants to spawn an actor as a child of the guardian (to be honest, I'm not sure when you'd want to do this from inside of another actor: the purpose of the SpawnProtocol
is for code outside of an actor), you just send a SpawnProtocol.Spawn
to systemGuardian
.
It's also worth noting that the SpawnProtocol
can be handled by an actor which isn't the guardian: the guardian actor can spawn an actor handling the SpawnProtocol
and provide a ref to that actor as a means to spawn an actor which won't be a child of the requestor.
Note that the ActorRef
for the ActorSystem
is the guardian actor and it is the guardian actor that will spawn the actor when you do system.tell(new SpawnProtocol.Spawn...)
.