我有以下驱动程序/主类封装我的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? } } }
所以手头的问题是如何安全/正确地将Cluck消息传递给FizzBuzz#onCluck(Cluck),它存在于actor系统之外?我可以提供一个关于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(有)非演员/驱动程序,以及一万个ChickenCluckDetector演员.想法?
解决方法
if there’s only one FizzBuzz (which there is) non-actor/driver,and ten thousand ChickenCluckDetector actors
那么最好为所有这些ChickenCluckDetectors创建一个共同的父级.然后,这个父母可以安全地保存对FizzBuzz的引用,从他所有的孩子那里收到cluck并调用onCluck方法.
在演员之外获取消息的一个选择是询问.在Scala中有演员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); } } }