Akka:在演员系统之外回传?

sme*_*eeb 7 java actor akka

我有以下驱动程序/主类封装我的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
    }
}
Run Code Online (Sandbox Code Playgroud)

以下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?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,在手头的问题是如何安全/正常传递Cluck消息FizzBuzz#onCluck(Cluck),这生活之外的演员系统?可以像这样提供FizzBuzz参考ChickenCluckDetector:

class ChickenCluckDetector extends UntypedActor {
    FizzBuzz fizzBuzz

    @Override
    void onReceive(Object message) {
        if(message instanceof Cluck) {
            Cluck cluck = message as Cluck

            fizzBuzz.onCluck(cluck)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我有一种感觉,这违反了Akka的最佳实践,并可能导致各种基于并发的问题,特别是如果只有一个FizzBuzz(有)非演员/驱动程序和一万个ChickenCluckDetector演员.想法?

Qui*_*zie 3

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

那么最好为所有这些 ChickenCluckDetector 创建一个公共父级。然后,该父级可以安全地保存对 FizzBu​​zz 的引用,接收来自所有子级的咯咯声并调用 onCluck 方法。

从参与者之外获取消息的一种选择是询问。在 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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)