并行执行多个任务,从第一个完成的中选择答案
Execute multiple tasks in parallel, pick answer from first completed
我有 n
不同的来源,例如,获取美元对欧元的汇率。令 n = 3
和来源为 Google、Yahoo、MyRates 以及相应的方法:
def getYahooRate:Double = ???
def getGoogleRate:Double = ???
def getMyRate:Double = ???
我想查询美元对欧元的汇率,以便并行轮询所有 n
源,并立即返回要接收的第一个响应。如果 none 在指定的时间范围内回复,则抛出异常。
使用 Scala(以及必要时使用 Akka)实现此功能的规范方法是什么?
是否有任何库方法可以完成大部分工作?
编辑:这是我尝试过的。对代码的一些评论将不胜感激:
这有点像 . The code for the below method is based on this SO answer
中 trycatch
的平行版本
type unitToT[T] = ()=>T
def trycatchPar[B](list:List[unitToT[B]], timeOut:Long):B = {
if (list.isEmpty) throw new Exception("call list must be non-empty")
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.concurrent.duration._
import scala.util.Failure
import scala.util.Success
val p = promise[B]
val futures = list.map(l => Future{l()})
futures foreach {
_ onComplete {
case s @ Success(_) => {
// Arbitrarily return the first success
p tryComplete s
}
case s @ Failure(_) =>
}
}
Await.result(p.future, timeOut millis)
}
您可以使用Future.firstCompletedOf
val first = Future.firstCompletedOf(futures)
Await.result(first, timeOut.millis)
我有 n
不同的来源,例如,获取美元对欧元的汇率。令 n = 3
和来源为 Google、Yahoo、MyRates 以及相应的方法:
def getYahooRate:Double = ???
def getGoogleRate:Double = ???
def getMyRate:Double = ???
我想查询美元对欧元的汇率,以便并行轮询所有 n
源,并立即返回要接收的第一个响应。如果 none 在指定的时间范围内回复,则抛出异常。
使用 Scala(以及必要时使用 Akka)实现此功能的规范方法是什么?
是否有任何库方法可以完成大部分工作?
编辑:这是我尝试过的。对代码的一些评论将不胜感激:
这有点像
trycatch
的平行版本
type unitToT[T] = ()=>T
def trycatchPar[B](list:List[unitToT[B]], timeOut:Long):B = {
if (list.isEmpty) throw new Exception("call list must be non-empty")
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.concurrent.duration._
import scala.util.Failure
import scala.util.Success
val p = promise[B]
val futures = list.map(l => Future{l()})
futures foreach {
_ onComplete {
case s @ Success(_) => {
// Arbitrarily return the first success
p tryComplete s
}
case s @ Failure(_) =>
}
}
Await.result(p.future, timeOut millis)
}
您可以使用Future.firstCompletedOf
val first = Future.firstCompletedOf(futures)
Await.result(first, timeOut.millis)