2017-08-08 4 views
0

postStopメソッドを使用して停止したときにクリーンアップジョブを実行したい俳優p: ParentActorがあります。仕事の1つは、子供の俳優c: ChildActorにメッセージを送信することです。その後、c、次にpを停止する必要があります。しかし、一度context.stop(p)と呼ばれると、すぐに停止しているようで、メッセージを受け取ることができません。cエラーメッセージの親アクターが停止したときに子供のAkka俳優をすぐに停止しないでください

class ParentActor extends Actor { 
    ... 
    override def postStop { 
    logger.info("Shutdown message received. Sending message to child...") 
    val future = c ? "doThing" 
    logger.info("Waiting for child to complete task...") 
    Await.result(future, Duration.Inf) 
    context.stop(c) 
    logger.info("Child stopped. Stopping self. Bye!") 
    context.stop(self) 
    } 
} 

結果::以下

は私がやりたいものの一例である

[ERROR] [SetSystem-akka.actor.default-dispatcher-5] [akka://SetSystem/user/ParentActor] Recipient[Actor[akka://SetSystem/user/ParentActor/ChildActor#70868360]] had already been terminated. Sender[Actor[akka://SetSystem/user/ParentActor#662624985]] sent the message of type "java.lang.String". 

代替は、シャットダウンに言っpメッセージを送ることであろうと、上記のアクションがその結果として起こることがありますが、組み込みの停止機能を使用するほうが優れています。

PS。これは新しいアプリケーションなので、設計の選択肢は大歓迎です。

答えて

1

俳優Aが停止すると、その子は実際にはApostStopフックが呼び出される前に停止しています。 (公式documentationから)次のように俳優が停止された一連のイベントは次のとおりです。二段階で俳優の進行の

終端:最初の俳優は、そのメールボックスの処理を中断して、そのすべての子に停止コマンドを送信します最後のメッセージがなくなるまで子機からの内部終了通知を処理し続けます(postStop、メールボックスをダンプし、DeathWatchにTerminatedを発行し、そのスーパーバイザに通知します)。

親のpostStopを無効にしても、お子様にメッセージを送信して返信を待つことが含まれます。親が終了すると、その子は親のpostStopが実行される前に停止します。

前述のとおり、ParentActorに特定のメッセージを送信してシャットダウンを開始する方法もあります。次のようなものは動作します:1は俳優でAwaitを使用しないでください

import akka.pattern.pipe 

class ParentActor extends Actor { 
    ... 
    def receive = { 
    case Shutdown => 
     (c ? DoYourThing).mapTo[ThingIsDone].pipeTo(self) 
    case ThingIsDone => 
     logger.info("Child has finished its task.") 
     context.stop(self) 
    case ... 
    } 
} 

注意を。代わりに、pipeFutureの結果をアクタに返します。

関連する問題