Reputation: 7141
I have a scenario where I have a Future[Something]
: a
which when successful needs to trigger a second Future[Unit]
: b
. I want to chain a
and b
together but I only care that a
succeeds. if b
fails I can just log an error and leave it at that:
So far I have:
def updateSomething(something: Something): Future[Something] = {
val eventual: Future[Something] = repository.update(something)
eventual.onSuccess({
case updated =>
repository.audit(updated.id, "Update successful")
.onFailure({
case throwable: Throwable => Logger.error("Audit failed", throwable)
})
Logger.info("Update Complete")
})
eventual
}
But this does not link the lifecyles of the update
and the audit
together. e.g when I Await.result(service.updateSomething(...), duration)
there is no guarantee the repository.audit
future has completed.
Upvotes: 1
Views: 309
Reputation: 547
also, you can just use a val
val = a <- executeA()
a.andThen{ case _ => executeB(b).recover{case e => println(e)} }
a //and return a
Upvotes: 0
Reputation: 1356
flatMap
is your friend. You can just use a for-comprehension + recover:
for {
a <- executeA()
_ <- executeB(b).recover{case e => println(e); Future.unit } // awaits B to complete
} yield a
Upvotes: 4
Reputation: 152
Also you can use more friendly form:
execudeA().flatMap(a =>
executeB().recover { case e => println(e); () }.map(_ => a)
)
Upvotes: 0