2016-05-02 12 views
0

データベースの更新を調整している俳優がいます。前の操作が完了した後で各操作が実行されるようにする必要があります。 これは操作Bが操作Aの結果を再利用するためです。Akkaを使用して順次操作を実行する必要があります

ここでは俳優のために書いたコードです。

class DbUpdateActor(databaseOperations: DBProvider) extends Actor { 

    implicit val ec:ExecutionContext = context.system.dispatcher 

    def receive: Receive = { 

    case newInfo : UpdateDb => 

     val future = Future { 
      // gets the current situation from DB 
      val status = databaseOperations.getSituation() 
      // do db update 
      databaseOperations.save(something) 
     } 

     future onComplete { 
     case Success(result: List[Int]) => 
      // 
     case Failure(err: Throwable) => 
      // 
     } 
    } 
} 

コードは1回の操作で正常に動作します。 2つの更新を起動すると、2番目の更新は非同期に実行されるため、最初の更新が完了する前に開始されます。

私は異なるタイプのメールボックスについて読んでいましたが、別のタイプのメールボックスがあれば役立つでしょうか。

提案がありますか?

答えて

1

あなたが探索できる1つのオプションは、そのFutureを削除し、そのブロックするdbコードをアクター内で実行できるようにすることです。次に、別のディスパッチャ(おそらくPinnedDispatcher)を使用して、メインアクタシステムのディスパッチャからこのブロッキングコードを起動し、実行するスレッドを与えます。本文をブロックしてそれを削除することで、アクターのメールボックスを適切に順番に実行することができます。

object DbUpdateActor{ 
    def props(databaseOperations:DBProvider) = 
    Props(classOf[DbUpdateActor], databaseOperations). 
     withDispatcher("db-update-dispatcher") 
} 

class DbUpdateActor(databaseOperations: DBProvider) extends Actor { 
    def receive: Receive = { 

    case newInfo : UpdateDb => 
     val status = databaseOperations.getSituation() 
     databaseOperations.save(something) 
    } 
} 

を次にあなたは以下のディスパッチャは、あなたの役者システムの設定で構成されていた限り、:次のように変化のラフスケッチはその仕事を作るために

db-update-dispatcher { 
    executor = "thread-pool-executor" 
    type = PinnedDispatcher 
} 

そして、あなたが起動そのようなDB更新俳優:

val updater = system.actorOf(DbUpdateActor.props(databaseOperations)) 

は、その後、あなたはマイナスのメインディスパッチャのスループットに影響を与えないような方法でコードを遮断することを実行するように、この俳優を設定するすべて設定する必要があります。

+0

非常にうまく機能しました。私は未来のブロックが、俳優を忙しくしておき、未来のブロックが完了した後で次のメッセージに進むことを期待していました。私は何が欠けていますか? – abx78

+1

'Future'(あなたのケースでは' onComplete'のような)に登録するコールバックは、完全に別のスレッドよりも非同期的に処理されます。つまり、現在のスレッドでのコードの実行は継続されます。あなたのケースでは、 'Future'の後にコードがなくなるので、アクターはそのメッセージの処理を完了し、次のメッセージに移ります。このため、未来と俳優を混在させるように注意する必要があります。 – cmbaxter

+0

すごく、説明のおかげで。 – abx78

0

これについてはどうすればよいですか?子が完了すると、それは完了したというメッセージを親に送信します。次に、既存の子供または新しい子供のいずれかで操作Bを開始することができます。

関連する問題