Akka:在 actor 系统之外进行通信?
Akka: communicating back outside the actor system?
我有以下 driver/main class 封装了我的 Akka 程序:
// 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
}
}
以及以下 ChickenCluckDetector
演员:
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?
}
}
}
所以手头的问题是如何safely/properly将Cluck
消息传递给FizzBuzz#onCluck(Cluck)
,住在外面 ] 演员系统? 我 可以 提供对 ChickenCluckDetector
的 FizzBuzz
引用,如下所示:
class ChickenCluckDetector extends UntypedActor {
FizzBuzz fizzBuzz
@Override
void onReceive(Object message) {
if(message instanceof Cluck) {
Cluck cluck = message as Cluck
fizzBuzz.onCluck(cluck)
}
}
}
但我觉得这违反了 Akka 的最佳实践,可能会导致各种基于并发的问题,尤其是如果只有一个 FizzBuzz
(确实有)non-actor/driver 和一万个ChickenCluckDetector
演员。想法?
if there's only one FizzBuzz (which there is) non-actor/driver, and ten thousand ChickenCluckDetector actors
那么最好为所有这些 ChickenCluckDetectors 创建一个通用的 parent。这个 parent 然后可以安全地保存对 FizzBuzz 的引用,从他的所有 children 接收咯咯声并调用 onCluck 方法。
在 actor 之外获取消息的一个选项是询问。在 Scala 中有 actor DSL(添加只是为了完整性)。但我相信您的示例中不需要这些。
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);
}
}
}
我有以下 driver/main class 封装了我的 Akka 程序:
// 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
}
}
以及以下 ChickenCluckDetector
演员:
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?
}
}
}
所以手头的问题是如何safely/properly将Cluck
消息传递给FizzBuzz#onCluck(Cluck)
,住在外面 ] 演员系统? 我 可以 提供对 ChickenCluckDetector
的 FizzBuzz
引用,如下所示:
class ChickenCluckDetector extends UntypedActor {
FizzBuzz fizzBuzz
@Override
void onReceive(Object message) {
if(message instanceof Cluck) {
Cluck cluck = message as Cluck
fizzBuzz.onCluck(cluck)
}
}
}
但我觉得这违反了 Akka 的最佳实践,可能会导致各种基于并发的问题,尤其是如果只有一个 FizzBuzz
(确实有)non-actor/driver 和一万个ChickenCluckDetector
演员。想法?
if there's only one FizzBuzz (which there is) non-actor/driver, and ten thousand ChickenCluckDetector actors
那么最好为所有这些 ChickenCluckDetectors 创建一个通用的 parent。这个 parent 然后可以安全地保存对 FizzBuzz 的引用,从他的所有 children 接收咯咯声并调用 onCluck 方法。
在 actor 之外获取消息的一个选项是询问。在 Scala 中有 actor DSL(添加只是为了完整性)。但我相信您的示例中不需要这些。
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);
}
}
}