Futures patterns

Dependency

Akka offers tiny helpers for use with FuturesCompletionStage. These are part of Akka’s core module:

sbt
val AkkaVersion = "2.6.10+80-485e21c9"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % AkkaVersion
Maven
<properties>
  <akka.version>2.6.10+80-485e21c9</akka.version>
  <scala.binary.version>2.12</scala.binary.version>
</properties>
<dependency>
  <groupId>com.typesafe.akka</groupId>
  <artifactId>akka-actor_${scala.binary.version}</artifactId>
  <version>${akka.version}</version>
</dependency>
Gradle
versions += [
  AkkaVersion: "2.6.10+80-485e21c9",
  ScalaBinary: "2.12"
]
dependencies {
  compile group: 'com.typesafe.akka', name: "akka-actor_${versions.ScalaBinary}", version: versions.AkkaVersion
}

After

akka.pattern.afterakka.pattern.Patterns.after makes it easy to complete a FutureCompletionStage with a value or exception after a timeout.

Scala
val delayed =
  akka.pattern.after(200.millis)(Future.failed(new IllegalStateException("OHNOES")))

val future = Future { Thread.sleep(1000); "foo" }
val result = Future.firstCompletedOf(Seq(future, delayed))
Java
import akka.pattern.Patterns;

CompletionStage<String> failWithException =
    CompletableFuture.supplyAsync(
        () -> {
          throw new IllegalStateException("OHNOES1");
        });
CompletionStage<String> delayed =
    Patterns.after(Duration.ofMillis(200), system, () -> failWithException);

Retry

akka.pattern.retryakka.pattern.Patterns.retry will retry a FutureCompletionStage some number of times with a delay between each attempt.

Scala
import akka.actor.typed.scaladsl.adapter._
implicit val scheduler: akka.actor.Scheduler = system.scheduler.toClassic
implicit val ec: ExecutionContext = system.executionContext

//Given some future that will succeed eventually
@volatile var failCount = 0
def futureToAttempt() = {
  if (failCount < 5) {
    failCount += 1
    Future.failed(new IllegalStateException(failCount.toString))
  } else Future.successful(5)
}

//Return a new future that will retry up to 10 times
val retried: Future[Int] = akka.pattern.retry(() => futureToAttempt(), attempts = 10, 100 milliseconds)
Java
import akka.pattern.Patterns;

Callable<CompletionStage<String>> attempt = () -> CompletableFuture.completedFuture("test");

CompletionStage<String> retriedFuture =
    Patterns.retry(attempt, 3, java.time.Duration.ofMillis(200), system);
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.