[英]Orchestrating child actors in Akka
我是Akka的新手,我想知道我應該如何處理將工作委托給其他(兒童)演員的演員,但是在哪里:
假設我有以下兒童演員(無論他們做什么):
// 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
才能繼續參與或調用ActorB
, ActorC
或ActorD
。 ActorB
和ActorC
,但是MasterParent
必須等待兩者的響應,然后才能繼續進行並調用/調用ActorD
換句話說,當MasterParent
接收到ProcessData
消息時:
ActorA
並等待其返回結果; 然后 ActorB
和ActorC
並等待它們的結果; 然后 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.