3

私は akka アクター間のメッセージング プロセスを構築して、マスターがワーカーに仕事を与え、それを監視していることを表現しようとしています。私の質問は

  1. 以下で私が提案しているのは、合理的なアプローチであり、
  2. そうでない場合でも、Future 教育のために、Futures の構成で適切に行う方法を知りたいです。

私が望むプロセスは次のようになります

1)マスターはask. 5 秒以内に応答することを期待します。それ以外の場合、ワーカーはチャンスを逃したと見なされ、再度入札に参加する必要があります。

import context.dispatcher
implicit val timeout = Timeout(5 seconds)
val workCompletedFuture = (worker ? WorkTicket(work)).mapTo[Future[WorkCompleted]]

2a)ワーカーが 5 秒以内に応答しない場合は、マスターに、作業を再割り当てするようにというメッセージを自分自身に送信してもらいたいと思います。

self ! WorkAllocationFailed(work, worker)

2b)ワーカーが応答した場合は、Future[WorkCompleted] が返されます。その未来が完成するのを、例えば2分くらい待ってみたいです。

3a) Future[WorkCompleted] がタイムアウト内に完了しない場合、作業を再割り当てする

self ! WorkFailed(work, worker)

3b) Future[WorkCompleted] が成功した場合、結果を収集します

このロジックを作成しようとしましたが、ネストされた で混乱しonComplete、Future[WorkCompleted] でタイムアウトを行う方法がわかりません。Akka 2.10 Futures docsを読んでみましたが、解決策がわかりませんでした。

4

2 に答える 2

2

ワーカーのプールにジョブを渡すマスターがあるという一般的な考えは、健全なパターンです。

一方、システムのすべての部分がすでにアクターである場合は、Future を使用することはお勧めしません。ask を使用して作業を送信する代わりに、tell を使用して送信することができます。その後、マスターはタイムアウトになったジョブを定期的にチェックし、それらを再送信できます。

また、アクターの本体で onComplete を呼び出すと、別のスレッドで実行される可能性があるため、非常に危険です。アクターと通信する安全な方法は、メッセージ パッシングです。Future があり、Future が完了したときにアクターで何かを実行したい場合は、パイプ パターンを使用することをお勧めします。

スニペットにも小さなバグがあります。ワーカー アクターが WorkCompleted で応答する場合、これが本当に必要な行です。

val workCompletedFuture = (worker ? WorkTicket(work)).mapTo[WorkCompleted]
于 2013-01-14T12:30:14.193 に答える
2

Endreの答えに同意します-すべて非常に良い点です。

これはどう:

1)タイムアウトのために自分自身へのメッセージをスケジュールします(を使用system.scheduler.scheduleOnce

2) 通常の方法でワーカーに作業メッセージを送信するtell

3a) 完了した作業がタイムアウト メッセージの前に戻ってきた場合は、スケジュールされたジョブをキャンセルし、手順 1 と 2 を使用して作業を再割り当てします。

3b) タイムアウト メッセージの後に完了した作業が戻ってきた場合は、それを無視するか、再割り当てされた作業をキャンセルします。

特に作業に時間がかかる場合や作業がブロックされている場合に、future が役立つ場所の 1 つがワーカーです。ワーカーは Future を使用して作業を行い、作業をキャンセルするなど、より多くの受信メッセージを処理するために利用可能のままにすることができます。

于 2013-01-14T13:51:45.037 に答える