2017-10-15 3 views
0

何らかの理由で、gRPCとAkkaを同時に使用する必要があります。この俳優がトップの俳優として始められるとき、何も間違っていません(この小さなデモでは)。しかし、それは子役になったとき、それはすべてのメッセージを受け取ることができず、次のように記録されます。ExecutionContextはAkkaデッドレターを引き起こします

[default-akka.actor.default-dispatcher-6] [akka://default/user/Grpc] Message [AkkaMessage.package$GlobalStart] from Actor[akka://default/user/TrackerCore#-808631363] to Actor[akka://default/user/Grpc#-1834173068] was not delivered. [1] dead letters encountered. 

例コア:

:私はのような新しい ExecutionContextを作成しようとしました

class GrpcActor() extends Actor { 
    val ec = scala.concurrent.ExecutionContext.global 
    val service = grpcService.bindService(new GrpcServerImpl(), ec) 
    override def receive: Receive = { 
     case GlobalStart() => { 
      println("GlobalStart") 
     } 
     ... 
    } 
} 

scala.concurrent.ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10)) 

なぜこのようなことが起こりますか、このようなデッドレターの問題をデバッグするにはどうすればよいですか(例外はスローされません)。

更新:

申し訳ありませんが、ここにすべての情報は表示されませんでした。私は正常なMainメソッドを使用して、GrpcActorをトップアクターとしてテストし、ScalaTestを子アクターとしてテストすることは間違いです。

class GrpcActorTest extends FlatSpec with Matchers{ 
    implicit val system = ActorSystem() 
    val actor: ActorRef = system.actorOf(Props[GrpcActor]) 
    actor ! GlobalStart() 
} 

この空のテストスイートは、アクターシステム全体をアクティブシャットダウンします。しかし問題はこの行にあります

val service = grpcService.bindService(new GrpcServerImpl(), ec) 

シャットダウン後にはGlobalStart()の配信が遅れました。

この行がないと、シャットダウン前にメッセージを配信できます。

これは正常な動作ですか?

(私の推測:GlobalStart()は、いくつかの重い仕事を行なったし、時間差を作り、そのラインでのシャットダウンメッセージ、後にキューに入れられたことが起こった)

+0

文法の間違いを訂正してこの問題を解決するための@chunjefに感謝します。 – Skye347

答えて

0

一つの方法は、servicelazy valを作ることです。

class GrpcActor extends Actor { 
    ... 
    lazy val service = grpcService.bindService(new GrpcServerImpl(), ec) 
    ... 
} 

lazy valが長時間実行操作のために有用である:中この場合、最初に使用されるまでserviceの初期化が延期されます。 lazy修飾子がなければ、serviceはアクタの作成時に初期化されます。

別のアプローチは、俳優が完全に初期化される前にシャットダウンから役者システムを防ぐために、あなたのテストでThread.sleepを追加することです:

class GrpcActorTest extends FlatSpec with Matchers { 
    ... 
    actor ! GlobalStart() 
    Thread.sleep(5000) // or whatever length of time is needed to initialize the actor 
} 

(注意点として、あなたのためのアッカTestkitを使用することを検討してください)

0

にのprintlnを追加し、その親にスーパーバイザ戦略を追加します。アクターのライフサイクル。あなたの俳優を殺す何かがあります。最後に、あなたは完全な例を提供する場合多分私はより多くを語ることができます:)問題に対処する

関連する問題