0

I have n different sources to, say, gets rates of USD to EUR. Let n = 3 and the sources be Google, Yahoo, MyRates with corresponding methods:

def getYahooRate:Double = ???
def getGoogleRate:Double = ???
def getMyRate:Double = ???

I want to query the rate of USD to EUR in such a way that all n sources are polled in parallel and the first response to be received is immediately returned. If none reply within a specified time-frame, then an exception is thrown.

What is the canonical way to implement this using Scala (and if necessary Akka)?

Is there any library method that does most of this?

EDIT: Here is what I have tried. Some comments on the code would be appreciated:

This is somewhat like a parallel version of trycatch from this SO question. The code for the below method is based on this SO answer

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)
}
Community
  • 1
  • 1
Jus12
  • 17,824
  • 28
  • 99
  • 157

1 Answers1

3

You can use Future.firstCompletedOf

val first = Future.firstCompletedOf(futures)
Await.result(first, timeOut.millis)
drexin
  • 24,225
  • 4
  • 67
  • 81
  • After a bit of trial, this does not behave as expected. If the first one gives failure, it returns that instead of waiting for success, unlike the code I pasted. – Jus12 Aug 13 '16 at 15:07