2016-08-16 37 views
0

は、私は、次の役者があるとのコールを頼みます最後のステップ(ロック)が完了した後のメソッド呼び出し側に対するReadResponseシーケンス

私は理解のためのアプローチが好きですが、もっと柔軟に書き込むにはどうすればいいですか?たとえば、Unlockが最初のステップでUnlockResponse(true)を返した場合はRead onlyを続行しますが、UnlockResponse (偽)?あなたはScala Promises API使用できるシーケンシャルロジックの

+0

あなただけの俳優と 'semaphore'のようなものを実装しようとしていますか? –

+0

ロック解除要求の値を調べるために、理解のためにガード条件を追加しようとしましたか? – cmbaxter

答えて

1

は、ちょうどそうのように、その中にガード条件で用-理解を使用します。

val result = 
    for{ 
    unlockResult <- (nActorRef ? Unlock).mapTo[UnlockResponse] 
    if unlockResult.result == true 
    readResult <- (anActorRef ? Read).mapTo[ReadResponse] 
    } yield readResult 

この場合の唯一の問題は、resultによって表される結果Futureが可能になるということですそのガード条件が満たされないときに失敗しました。それはあなたのための問題だ、とあなたは多分FutureではなくOption[ReadResult]をラップしたい場合は、そのようrecoverを使用することができます。

val result:Future[Option[ReadResult]] = 
    for{ 
    unlockResult <- (nActorRef ? Unlock).mapTo[UnlockResponse] 
    if unlockResult.result == true 
    readResult <- (anActorRef ? Read).mapTo[ReadResponse] 
    } yield Some(readResult) 

result.recover{case ex:NoSuchElementException => None} 
+0

ありがとうございます。このアプローチはよりきれいに見え、プロセスを簡単に制御するためにガードを使用することができます。 –

1

:あなたは

p.future.onComplete { 
    case Success(somedata) => { 
     processData(somedata) 
     anActorRef ! Lock 
    } 
    case Failure(t) => logger.error(t) 
} 

ような何かを行うことができ、結果に応じて、その後

val promise = Promise[ReadResponse]() 
val unlockFuture = anActorRef ? Unlock 
unlockFuture.map{ 
    case UnlockResponse (true) => promise.completeWith(anActorRef ? Read) 
    case UnlockResponse (false) => p.failure(new IllegalStateException) 
} 

とを同じ順次効果でよりエレガントな解決策が考えられトランザクションのロジックが送信者ではなくアクター自身によって処理される、アクターが成立する/達成されないこととstashによって達成される。私は私のコメントで述べたように

+0

ありがとうございます。これはうまく見えますが、Read()の前にシーケンスで余分なアクタコールを追加すると問題になります。私は、2つの先物の結果を順番にして約束を果たすことができますか?それとも2つの約束が必要ですか? –

+0

これは正しくありません。そのaskオペレーションが 'unlockFuture'に適用されている' map'オペレーションの外にあるので、アンロックの結果にかかわらずここで読み込みを消します。ロック解除が成功した場合にのみ読み込みを中止したい場合は、アンロック結果が真であった場合にそのask操作を 'map'に移動する必要があります。 – cmbaxter