I was wondering what is a comprehensive list of major differences between scala.util.Success and akka.actor.Status.Success?
And in what cases are they interchangable, if at all?
akka.actor.Status.Success
is a wrapper which can be used as a message to quickly indicate to another actor that some operation completed successfully. Accordingly it provides no API beyond extraction.
scala.util.Success[T]
is one of the two subtypes of scala.util.Try
, which is a monadic(-ish, it doesn't fully obey the monad laws, for a good reason) representation of an operation that can fail (in this case, Success
contains the result of a successful operation). It's fairly rare, in practice, to directly create scala.util.Success
s: you most often will create a Try
.
While they both encode some notion of "an operation was successfully attempted", scala.util.Success
pertains more to the operation itself and akka.actor.Status.Success
pertains more to the notification of success. In fact, it might well make sense, within the actor performing some operation which can fail, to have code like
import akka.actor.Status
import scala.util.{ Failure, Success, Try }
def attemptAndReport(reportTo: ActorRef)(operation: => Unit): Unit =
Try(operation) match {
case _: Success =>
// since it's a Unit-returning operation, there's only one value that could be wrapped by Success: ()
reportTo ! Status.Success("operation succeeded")
case Failure(e) =>
reportTo ! Status.Failure(e)
}
That code is a little contorted to shoehorn both Success
es. It would be more natural and useful to have something like
import scala.util.control.NonFatal
def attemptAndReport[Result](reportTo: ActorRef, successMsg: Result => Any)(operation: => Result): Unit = {
val reportMsg = Try(operation) // Try[Result]
.map(r => Status.Success(successMsg)) // Try[Status.Success]... icky, but this is Akka Classic...
.recover {
case NonFatal(e) => Status.Failure(e)
} // Try[Status]
reportMsg.foreach(reportTo ! _)
}