簡體   English   中英

在Akka安排兒童演員

[英]Orchestrating child actors in Akka

我是Akka的新手,我想知道我應該如何處理將工作委托給其他(兒童)演員的演員,但是在哪里:

  1. 其中一些兒童演員必須按照特定的順序參與;
  2. 這些子演員中的一些可以以任何順序參與,並且可以真正地與主要/父演員的動作異步執行

假設我有以下兒童演員(無論他們做什么):

// Grovy pseudo code
class ActorA extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof RunActorA) {
            …
    }
}
class ActorB extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof RunActorB) {
            …
    }
}
class ActorC extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof RunActorC) {
            …
        }
    }
class ActorD extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof RunActorD) {
            …
        }
    }

並說我有以下父級角色來調用它們:

class MasterParent extends UntypedActor {
    ActorRef actorA
    ActorRef actorB
    ActorRef actorC
    ActorRef actorD

    MasterParent(ActorRef actorA, ActorRef actorA, ActorRef actorA, ActorRef actorA) {
        super()

        this.actorA = actorA
        this.actorB = actorB
        this.actorC = actorC
        this.actorD = actorD
    }

    @Override
    void onReceive(Object message) {
        if(message instanceof ProcessData) {
            ProcessData pData = message as ProcessData
            Widget widget = pData.widget
            RunActorA runA = new RunActorA(widget)

            actorA.tell(runA, self)

            // Somehow obtain a result from A, perhaps an “ResultOfA” object.
            ResultOfA resultA = ??? // get from ActorA

            RunActorB runB = new RunActorB(resultA)
            RunActorC runC = new RunActorC(resultA)

            actorB.tell(runB, self)
            actorC.tell(runC, self)

            // Somehow wait until both B and C return a result, say, ResultOfB and ResultOfC, respectively.
            ResultOfB resultB = ??? // get from ActorB
            ResultOfC resultC = ??? // get from ActorC

            RunActorD runD = new RunActorD(resultB, resultC)

            actorD.tell(runD, self)
        }
    }
}

如你看到的:

  • ActorA必須首先“ 參與 ”(由父母調用),並且我們必須等待其響應,然后MasterParent才能繼續參與或調用ActorBActorCActorD
  • 可以異步/並行地相互調用ActorBActorC ,但是MasterParent必須等待兩者的響應,然后才能繼續進行並調用/調用ActorD

換句話說,當MasterParent接收到ProcessData消息時:

  1. 運行ActorA並等待其返回結果; 然后
  2. 同時運行ActorBActorC並等待它們的結果; 然后
  3. 運行ActorD

我的主要問題是: 如何實現這一目標(Java偽代碼或示例倍受贊賞!)?

其次,更重要的是,因為我對演員還很陌生: 這種親子編排在Akka中是否“正常”? 還是,Akka最佳實踐是否通常會規定所有子代異步運行,而沒有施加順序/命令/編排?

首先,是的,因為MasterParent將工作委派給其他演員,所以將他們作為兒童演員是有意義的。

同樣,您對ResultOfA的想法也相距不遠。

這是您可以做到的一種方法:

ResultOfB resultB = null;
ResultOfC resultC = null;

@Override
void onReceive(Object message) {
    if(message instanceof ProcessData) {
        ProcessData pData = message as ProcessData

        resultB = null;
        resultC = null;

        Widget widget = pData.widget
        RunActorA runA = new RunActorA(widget)

        actorA.tell(runA, self)
    } else if (message instanceof ResultOfA) {
        ResultOfA resultA = message as ResultOfA

        actorB.tell(resultA)
        actorC.tell(resultA)
    } else if (message instanceof ResultOfB) {
        resultB = message as ResultOfB

        if (resultC != null) {
            actorD.tell(composedResultBAndC)
        }
    } else if (message instanceof ResultOfC) {
        resultC = message as ResultOfC

        if (resultB != null) {
            actorD.tell(composedResultBAndC)
        }
    } else if (message instanceof ResultOfD) {
        //Do stuff with the result
    }
}

每個子actor都將執行sender()。tell(resultX)的位置,以便主機可以接收結果。

ResultB和ResultC都需要,因此我在actor中保存了一些狀態,該狀態在ProcessData的每個新實例上都設置為null,因此在這種情況下無法將多個ProcessData發送到一個MasterParent。

如果您想不等待就將多個ProcessData消息發送到一個MasterParent,則需要使其保持無狀態,因此可以在actorB和actorC上使用Ask Pattern並一起解析返回的期貨。 所以像這樣:

Future futureA = actorB.ask(resultA)
Future futureB = actorC.ask(resultA)

然后編寫它們並注冊一個回調,然后在其中向actorD發送請求。

此代碼為偽編碼,因此不可運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM