How to fetch the first successful completed Future?

Viewed 163

Problem

I would like to make two parallel executions with the help of futures. One queries the cache and the another one the database. The caller should return the first successful completed future or the database future.


import scala.concurrent.{ExecutionContext, Future}

class UserServiceImpl(
    private val cacheRepository: CacheRepository, 
    private val databaseRepository: DatabaseRepository
)(implicit val executionContext: ExecutionContext) extends UserService {

    override def getUserByName(username: String): Future[User] = {
        val cacheFuture: Future[User] = Future {
            cacheRepository.getUser(username)
        }
        val databaseFuture: Future[User] = Future {
            databaseRepository.getUser(username)
        }

        // now return the first successful finished Future[User] or the databaseFuture if completed.
    }
}
1 Answers

It looks like Future.find() might be what you want. According to the docs it returns, "the first Future with a result that matches the predicate", and also, "...failed Futures will be ignored." So all you need is a predicate that holds true for any returned User.

If User were a String, for example, then the following should work.

Future.find(List(cacheFuture,databaseFuture))(_.nonEmpty)

Note that this returns a Future[Option[User]] in case no User is found.

Related