【问题标题】:Akka: communicating back outside the actor system?Akka:在actor系统之外进行通信?
【发布时间】:2015-07-01 21:21:33
【问题描述】:

我有以下封装我的 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 系统之外?可以像这样提供FizzBuzzChickenCluckDetector的引用:

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 参与者.想法?

【问题讨论】:

    标签: java akka actor


    【解决方案1】:

    如果只有一个 FizzBu​​zz(有)非演员/司机,以及一万个 ChickenCluckDetector 演员

    那么最好为所有这些 ChickenCluckDetector 创建一个共同的父级。然后,这个父级可以安全地持有对 FizzBu​​zz 的引用,接收来自他所有子级的咯咯声并调用 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);
            }
        }
    
    }
    

    【讨论】:

    • 感谢@Quizzie (+1) - 对于赏金,您介意添加代码/伪代码示例吗?你的意思是一个以某种方式管理其他实例的ChickenCluckDetector 父实例,还是一个完全独立的ChickenCluckDetectorMaster 演员,如果是这样,它会是什么样子?再次感谢!
    • 在 Akka 中,引入 Actor 层级总是一个好主意,在这种层级中,父母监督他们的孩子,给他们工作,收集他们的工作成果,决定他们崩溃时会发生什么......
    • 再次感谢@Quizzie (+1) - 最后 后续问题,我保证!您似乎表明在上面的代码示例中,有一个演员层次结构,其中ChickenCluckMaster 正在监督ChickenCluckDetector 实例......**代码中的“监督”发生在哪里?** 它是否以某种方式在创建孩子时的引擎盖(Props.create(...))?这与我一直听说的OneForOneStrategyAllForOneStrategy 有什么关系?再次感谢!
    • 阅读官方文档中的这些页面,它们很好地解释了一切:doc.akka.io/docs/akka/2.3.10/general/supervision.htmldoc.akka.io/docs/akka/2.3.10/java/fault-tolerance.html ...如果您对 Akka 很认真,我强烈建议您阅读大部分文档。跨度>
    猜你喜欢
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 2020-05-16
    • 2013-01-25
    • 1970-01-01
    相关资源
    最近更新 更多