Simão Martins
Simão Martins

Reputation: 1240

Future pipeTo failure is wrapped inside akka.actor.status.Failure?

When using the pipe pattern in Akka the future failed result is wrapped inside a akka.actor.status.Failure, however the future success result is NOT wrapped in the corresponding akka.actor.status.Success.

I was wondering what is the reasoning behind this decision? Why just the failure and not the success?

It seems more logical to not wrap anything at all.

Here is the link to the implementation: https://github.com/akka/akka/blob/v2.4-M2/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala

Upvotes: 3

Views: 2707

Answers (2)

cmbaxter
cmbaxter

Reputation: 35463

Let's say you have an actor A that sends a message to actor B and A expects some sort of response message from B. Inside of B, in order for it to do it's work, it needs a Future for some reason. After that Future completes, it wants to send the result back to A. The person who coded B wants to be careful to not close over the sender() when responding back to A, so they use the pipeTo pattern like so:

fut pipeTo sender()

Now back in A, you are expecting a response of a certain type, and you should not have to deal with the internal intricacies of actor B and the fact that it needed a Future in order to do it's work. In other words, you don't want the response to come back to you wrapped in a scala.util.Try (Success or Failure). If you expect a String, then if all goes well, that's exactly what you want back from B. But in the case that everything does not go well in B, A needs to know this and the way that the Akka team chose to do so was to wrap it in Status.Failure. This to me seems better than sending the raw Exception as is.

Now, us, we use a standard communication model between actors where we have something similar to this simple model (simplified for brevity):

sealed trait ServiceResult[+A]
case object EmptyResult extends ServiceResult[Nothing]
case class FullResult[+A](value:A) extends ServiceResult[A]
case class Failure(error:ErrorMessage, ex:Option[Throwable]) extends ServiceResult[Nothing]

All services always respond with some form of ServiceResult. So if we are piping back to a sender() from a Future we do something like this:

fut.recover{case ex => Failure(someErrorMessage, Some(ex)} pipeTo sender()

That way we don't have to really deal with Status.Failure anywhere.

Upvotes: 8

Quizzie
Quizzie

Reputation: 879

future onComplete will resolve to either scala.util.Success(futureResult) or scala.util.Failure(someThrowable).

If the future succeeds, it is convenient to get back the futureResult directly.

If the future failed, you probably don't want to receive back an unwrapped throwable. It's nicer to get it back wrapped in akka.actor.status.Failure.

Upvotes: 1

Related Questions