0

I have some functions which return Futures. The callers register callbacks by onComplete.

def makeHttpRequest(): Future[T] = ???
makeHttpRequest().onComplete {
  case Success(v) => ???
  case Failure(ex) => ???
}

Now I want to enable retries on these functions (or function callings). Is there any suggestion on how to achieve this?

user6502167
  • 731
  • 9
  • 18

2 Answers2

5

There is no retry capability out-of-the-box. However based on Retry a function that returns a Future consider

def retry[T](n: Int, expr: => Future[T]): Future[T] =
  Future.unit.flatMap(_ => expr).recoverWith {
    case e if n > 1 => retry(n - 1, expr)
    case e => Future.failed(e)
  }

retry(3, makeHttpRequest())

https://scalafiddle.io/sf/otseSX0/0

or consider dedicated library such as softwaremill/retry.

Scalway
  • 1,633
  • 10
  • 18
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
  • 2
    in first case clausure you need to have `case e if n > 1` not `case e if n > 0` to retry 3 times instead of 4. – Scalway Dec 23 '19 at 12:16
  • What if we want to wait for a while to make another attempt? `sleep` is not a great choice. Is there any other simple option? I'm using Akka/Scala, but don't want to reschedule the message to the actor. – user6502167 Dec 24 '19 at 03:04
0
def makeHttpRequest(maxRetryCount: Int, currentRetryCount: Int = 0): Future[T] = {
  val responseFuture = ???
  if (currentRetryCount == maxRetryCount)
    responseFuture
  else
    responseFuture.recoverWith(makeHttpRequest(maxRetryCount, currentRetryCount + 1))
}

makeHttpRequest(3).onComplete {
  case Success(v) => ???
  case Failure(ex) => ???
}
sarveshseri
  • 13,738
  • 28
  • 47