0

I have List[Future[String]] and would like to wait constant period of time in order to collect successfull computation as well as rerun operations for futures that do not complete in specified period of time.

In pseudo code it will look like:

val inputData: List[String] = getInputData()
val futures : List[Future[String]] = inputData.map(toLongRunningIOOperation)
val (completedFutures, unfinishedFutures) = Await.ready(futures, 2 seconds)
val rerunedOperations : List[Future[String]] = unfinisedFutures.map(rerun)

Such solution could be useful if you need to execute several calls to external services whose usual latency is (low p99 < 60ms) but sometimes requests are processed more than 5 seconds (because of current state/load). In such situation it is better to rerun those requests (i.e to another instance of the service).

baju
  • 511
  • 5
  • 19

1 Answers1

0

As an example, use Future.firstCompletedOf function to get timed future

def futureToFutureOption[T](f: Future[T]): Future[Option[T]] = f.map(Some(_)).recover[Option[T]]{case _ => None}
val inputData: List[String] = List("a", "b", "c", "d")
val completedFuture = inputData.map { a =>
  a match {
    case "a" | "c" => Future.firstCompletedOf(Seq(Future{Thread.sleep(3000); a},
      Future.failed{Thread.sleep(2000); new RuntimeException()}))
    case _ => Future(a)
  }
}

val unfinished = Future.sequence(completedFuture.map(futureToFutureOption)).map(list => inputData.toSet -- list.flatten.toSet)

val rerunedOperations: Future[Set[Future[String]]] = unfinished.map { _.map(foo) }

def foo(s: String): Future[String] = ???

Here in example rerunedOperations have different type as in yours example, but I think this will be fine for you. Also keep in mind, if you're performing some call to external system inside the future and that future didn't finish in appropriate time, such approach will not prevent unfinished future from execution, I mean that the actual call to external system will be processing while you will try to make another call

maks
  • 5,911
  • 17
  • 79
  • 123