Reputation: 8008
I've got the following piece of code on an Actor where I ask someone else for an action (persist something in an external DB)
If that is successful:
Then I send a message to myself to reflect the result of the action in my local state and then return that to the original sender
.
In case of a failure on the persistence to the DB:
Then I want to reply with Status.Failure
(as returned to me) directly to the current sender.
The code looks like this:
case Event(SomeAction(name), _) =>
val origin = sender()
ask(someOtherActor, SomeAction(name)).mapTo[ActionResult]
.map(ActionCompleted)
.onComplete {
case Success(value) => self.tell(value, origin)
case Failure(e) => origin ! Status.Failure(e)
}
stay()
case Event(ActionCompleted(result), state) =>
stay using state.update(result) replying result
The code above works, but I need to rely on copying the sender into a local variable to avoid closing over it.
I was wondering if there is any better way to do this with pipeTo
?
Upvotes: 1
Views: 343
Reputation: 13130
You can build your own pipeTo
that does what you need. I think routeTo
would be a good name for it.
implicit class RouteTo[A](f: Future[A]) {
import akka.pattern.pipe
def routeTo(successDestination: ActorRef,
failureDestination: ActorRef)(
implicit sender: ActorRef,
ec: ExecutionContext): Unit =
f onComplete {
case s @ Success(_) => successDestination.tell(s, sender)
case f @ Failure(_) => failureDestination.tell(f, sender)
}
}
import RouteTo._
Future("hello").routeTo(successRecipient, failureRecipient)
Upvotes: 3