繁体   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