利用 Guardian Actor 的 SpawnProtocol.Command
Utilizing SpawnProtocol.Command from Guardian Actor
我需要另一个演员的 ActorSystem<SpawnProtocol.Command>
。我希望 GuardianActor 有一个对 ActorSystem<SpawnProtocol.Command>
的引用,这样当我使用 Guardian Actor 生成 actor 时我可以传递这个引用,有什么办法可以做到这一点吗?我不认为这是可能的,因为我们只在创建演员系统和监护人后得到 ActorSystem<SpawnProtocol.Command>
。
ActorSystem<SpawnProtocol.Command> system = ActorSystem.create(GuardianActor.create(), "System", config)
我看到的唯一选择是做类似
的事情
system.tell(new SpawnProtocol.Spawn<>(NewActor.create(system)), "NewActor", Props.empty(), system.ignoreRef());
在这种情况下,我不会使用 guardian actor 生成 NewActor
- 我认为这不是一个干净的实现(如果我错了请纠正我)
如果我理解你的话,你想生成 actors 并引用 ActorSystem
。
每个演员都可以通过其 ActorContext
获得对其 ActorSystem
的引用; ActorContext
通常使用 Behaviors.setup
注入。您可以通过在 ActorContext
上调用 getSystem()
来获得 ActorSystem
。请注意,它是一个 ActorSystem<Void>
,但由于它真正使用其类型参数的唯一方法是当您将它用作 ActorRef
时,可以使用 unsafeUpcast()
方法。请注意,unsafeUpcast
不会以任何方式验证转换是否有效,但由于通常不会混淆类型(在典型应用程序中只有一个 ActorSystem
),这通常是'没问题;如果转换不当,将导致系统在发送消息时崩溃。
// 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>()
}
}
当 Actor1
想要生成一个 actor 作为守护者的 child 时(老实说,我不确定你什么时候想从另一个 actor 内部执行此操作: SpawnProtocol
的目的是用于 actor 之外的代码),您只需将 SpawnProtocol.Spawn
发送到 systemGuardian
.
还值得注意的是 SpawnProtocol
可以由不是监护人的演员处理:监护人演员可以产生一个处理 SpawnProtocol
的演员并提供对该演员的引用作为产生不会成为请求者 child 的参与者的一种方式。
请注意,ActorSystem
的 ActorRef
是守护者角色,当您执行 system.tell(new SpawnProtocol.Spawn...)
时,守护者角色将生成该角色。
我需要另一个演员的 ActorSystem<SpawnProtocol.Command>
。我希望 GuardianActor 有一个对 ActorSystem<SpawnProtocol.Command>
的引用,这样当我使用 Guardian Actor 生成 actor 时我可以传递这个引用,有什么办法可以做到这一点吗?我不认为这是可能的,因为我们只在创建演员系统和监护人后得到 ActorSystem<SpawnProtocol.Command>
。
ActorSystem<SpawnProtocol.Command> system = ActorSystem.create(GuardianActor.create(), "System", config)
我看到的唯一选择是做类似
的事情system.tell(new SpawnProtocol.Spawn<>(NewActor.create(system)), "NewActor", Props.empty(), system.ignoreRef());
在这种情况下,我不会使用 guardian actor 生成 NewActor
- 我认为这不是一个干净的实现(如果我错了请纠正我)
如果我理解你的话,你想生成 actors 并引用 ActorSystem
。
每个演员都可以通过其 ActorContext
获得对其 ActorSystem
的引用; ActorContext
通常使用 Behaviors.setup
注入。您可以通过在 ActorContext
上调用 getSystem()
来获得 ActorSystem
。请注意,它是一个 ActorSystem<Void>
,但由于它真正使用其类型参数的唯一方法是当您将它用作 ActorRef
时,可以使用 unsafeUpcast()
方法。请注意,unsafeUpcast
不会以任何方式验证转换是否有效,但由于通常不会混淆类型(在典型应用程序中只有一个 ActorSystem
),这通常是'没问题;如果转换不当,将导致系统在发送消息时崩溃。
// 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>()
}
}
当 Actor1
想要生成一个 actor 作为守护者的 child 时(老实说,我不确定你什么时候想从另一个 actor 内部执行此操作: SpawnProtocol
的目的是用于 actor 之外的代码),您只需将 SpawnProtocol.Spawn
发送到 systemGuardian
.
还值得注意的是 SpawnProtocol
可以由不是监护人的演员处理:监护人演员可以产生一个处理 SpawnProtocol
的演员并提供对该演员的引用作为产生不会成为请求者 child 的参与者的一种方式。
请注意,ActorSystem
的 ActorRef
是守护者角色,当您执行 system.tell(new SpawnProtocol.Spawn...)
时,守护者角色将生成该角色。