Reputation: 3716
Lately I've found myself wrapping actors in classes so that I get back a little of the typesafety I lose when dealing with ActorRef
s.
The problem is, at the end, that not only I need to send a specific message, I also need to cast the response to the expected result.
So I thought that I could send messages to actors that contain Promise
so that they could report the result eventually.
Is that a bad idea? It looks pretty neat to me... Is typesafe and works just as good. Why hasn't anyone come with the idea? Is there anything wrong with it that I haven't noticed?
ask pattern based solution
case class GetUser(id:Long)
(actorRef ! GetUser(1l)).mapTo[User]
class UserRepoActor extends Actor{
def receive={
case GetUser(id)=>
sender() ! getUser(id)
}
...
}
Promise based solution
case class GetUser(id: Long, resp: Promise[User])
val req = GetUser(1l,Promise())
actorRef ! req
req.resp.future // No casting!!
class UserRepoActor extends Actor{
def receive={
case GetUser(id,resp)=>
response.success(getUser(id))
}
...
}
Upvotes: 3
Views: 980
Reputation: 4017
Ask pattern is definitely better.
1) Actors are supposed to share no state and interact with the outer world via messages. Fulfilling the promise is actually a mutating shared variable
2) Passing the stateful objects into actor's creator (e.g. promise) breaks actor's lifecycle in case of restarts
So promise-based approach works in simple cases. But if you use it just like that probably you don't need such complicated stuff like akka at all?
Upvotes: 1
Reputation: 3482
Promise
s won't work in distributed actor system.
At least, without additional efforts for that.
Upvotes: 1
Reputation: 16328
There is nothing wrong. Very close approach is used in akka typed with the only difference: a single-use ActorRef[T]
is being sent instead of Promise[T]
Upvotes: 1