Akka / Scala承诺需要两个参与者来完成 [英] An Akka/Scala promise that requires two actors to complete

查看:72
本文介绍了Akka / Scala承诺需要两个参与者来完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Scala和Akka构建股票市场应用程序。市场匹配买卖双方,然后发送

  Promise [交易] 

给需要完成交易的买方和卖方(在某个时候),以便处理交易。



问题在于承诺可能会失败,因为其中之一


  1. 买方资金不足,

  2. 卖方的股票不足。

我如何创建需要两个参与者协调才能完成的Scala承诺?

解决方案

您不希望使用询问是正确的-应该尽可能避免使用这种方法。



在这里您可以将承诺发送给买方和卖方参与者,然后组成相应的期货,并在履行承诺时安排处理交易。

 导入scala.concurrent。{未来,承诺} 
导入scala.concurrent.ExecutionContext.Implicits.global

val fundPromise = promise [资金]
val股份Promise = promise [Shares]

BuyerActor! GetFunds(金额,资金承诺)
SellerActor! GetShares(numShares,股票,sharesPromise)

val futureFunds = fundsPromise.future
val futureShares = sharesPromise.future

val购买=
for {fund <-futureFunds;股票<-futureShares}
收益交易(资金,股票)

完成购买{
case Success(transactionResult)=>
BuyerActor! PutShares(numShares)
SellerActor! PutFunds(amount)
//告诉某人它工作了
情况Failure(t)=>
futureFunds onSuccess {case _ => BuyerActor! PutFunds(amount)}
futureShares onSuccess {case _ => SellerActor! PutShares(numShares)}
//告诉某人由于t
而失败}

请注意,最终的结果可能会因以下几个原因而失败:由于您无法从买方那里获得资金,因为您无法从卖方那里获得股票或由于 transact 。因此,一旦失败,我们将检查资金和股票期货,以查看是否获得了资金,如果是,我们会退还我们所收取的费用。期货中的c $ c> amount 和 numShares ,这意味着您希望它们成为val。如果它们是变量,那么当期货实际运行时,您最终可能会使用错误的值。



bsmk指出,这是假定 buyerActor sellerActor 与上述代码位于同一JVM中。如果没有,您可以让本地演员在听取远程演员的意见后处理诺言。如果有更好的方法,请在评论中让我知道。


I am building a stock market application using Scala and Akka. The market matches buyers and sellers and then sends a

Promise[Transaction]

to both the buyer and the seller that needs to be completed (at some point) in order for the transaction to be processed.

Issue is that the promise could complete with failure because either

  1. buyer has insufficient funds,
  2. seller has insufficient shares.

How can I create a Scala promise that requires the coordination of two actors to complete?

解决方案

You are right not to want to use ask -- that should be avoided when possible.

Here is how you can send Promises to buyer and seller actors, then compose the corresponding Futures and arrange to process the transaction when the Promises are fulfilled.

import scala.concurrent.{future, promise}
import scala.concurrent.ExecutionContext.Implicits.global

val  fundsPromise = promise[Funds]
val sharesPromise = promise[Shares]

 buyerActor ! GetFunds(amount, fundsPromise)
sellerActor ! GetShares(numShares, stock, sharesPromise)

val futureFunds =   fundsPromise.future
val futureShares = sharesPromise.future

val purchase =
  for { funds <- futureFunds; shares <- futureShares }
    yield transact(funds, shares)

purchase onComplete {
  case Success(transactionResult) =>
     buyerActor ! PutShares(numShares)
    sellerActor ! PutFunds(amount)
    // tell somebody it worked
  case Failure(t) =>
    futureFunds  onSuccess { case _ =>  buyerActor ! PutFunds(amount) }
    futureShares onSuccess { case _ => sellerActor ! PutShares(numShares) }
    // tell somebody it failed because of t
}

Note that the ultimate result can be failure for several reasons: because you could not get the funds from the buyer, because you could not get the shares from the seller, or because something went wrong in transact. So on failure we check the funds and shares futures to see whether we got them, and if so we give back what we took.

Also note that we close over amount and numShares in futures, which means that you want them to be vals. If they were vars, you could end up using the wrong values when the futures actually run.

As bsmk points out, this assumes that buyerActor and sellerActor are in the same JVM as the above code. If not, you could have a local actor handle the promise upon hearing from the remote actor; if there is a better way, please let me know in the comments.

这篇关于Akka / Scala承诺需要两个参与者来完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆