Dawid
Dawid

Reputation: 691

How to fetch the first successful completed Future?

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.
    }
}

Upvotes: 2

Views: 653

Answers (1)

jwvh
jwvh

Reputation: 51271

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.

Upvotes: 3

Related Questions