2015-04-23 13 views
7

Mam następujący sterownik/główne klasy zamykającą mój program Akka:Akka: komunikowanie się z powrotem poza systemem aktora?

// 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 
    } 
} 

i następujący ChickenCluckDetector Aktor:

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? 
     } 
    } 
} 

Więc problem pod ręką jest jak bezpiecznie/właściwie przekazać wiadomość Cluck do FizzBuzz#onCluck(Cluck), , który mieszka poza systemem aktorskim pod numerem? I mógłby zapewnić FizzBuzz odniesienie do ChickenCluckDetector tak:

class ChickenCluckDetector extends UntypedActor { 
    FizzBuzz fizzBuzz 

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

      fizzBuzz.onCluck(cluck) 
     } 
    } 
} 

Ale mam wrażenie ten jest niezgodny z najlepszych praktyk Akka i może spowodować wszelkiego rodzaju problemów współbieżności oparte, szczególnie jeśli istnieje tylko jeden FizzBuzz (co nie ma) aktor/kierowca i dziesięć tysięcy aktorów ChickenCluckDetector. Pomysły?

Odpowiedz

3

jeśli istnieje tylko jedna FizzBuzz (co tam jest), non-aktor/sterownik, a dziesięć tysięcy ChickenCluckDetector aktorów

Wtedy najlepiej byłoby stworzenie jednego wspólnego rodzica dla wszystkich tych ChickenCluckDetectors. Ten rodzic mógł następnie bezpiecznie przechowywać referencje do FizzBuzz, otrzymywać crypki od wszystkich swoich dzieci i wywoływać metodę onCluck.

Jedna z opcji uzyskiwania wiadomości poza aktorami. A w Scali jest aktor DSL (dodany tylko dla kompletności). Ale wierzę, że nie potrzebujesz żadnego z nich w swoim przykładzie.

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); 
     } 
    } 

} 
+0

Dzięki @Quizzie (+1) - po dobroci, czy mogłabyś dodanie przykład kod/pseudo-code? Czy masz na myśli instancję macierzystą 'ChickenCluckDetector', która w jakiś sposób zarządza innymi instancjami lub zupełnie oddzielnym aktorem' ChickenCluckDetectorMaster', a jeśli tak, to jak by to wyglądało? Dzięki jeszcze raz! – smeeb

+1

W Akce zawsze dobrze jest przedstawić hierarchię aktorów, w której rodzice nadzorują swoje dzieci, dają im pracę, zbierają wyniki swojej pracy, decydują, co się z nimi stanie, gdy się rozbiją ... – Quizzie

+0

Jeszcze raz dziękuję @Quizzie (+1) - * * ostatnie ** pytanie uzupełniające, obiecuję! Wydaje się wskazywać, że w powyższym przykładzie kodu istnieje hierarchia aktorów, w której 'ChickenCluckMaster' nadzoruje instancje' ChickenCluckDetector' ... ** gdzie w kodzie jest ten "nadzór"? ** Czy w jakiś sposób jest traktowany pod kaptur po utworzeniu dziecka ('Props.create (...)')? W jaki sposób wiąże się to z "OneForOneStrategy" i "AllForOneStrategy", o których słyszę? Dzięki jeszcze raz! – smeeb