caeus
caeus

Reputation: 3716

Akka Actors: ask pattern vs Promise

Lately I've found myself wrapping actors in classes so that I get back a little of the typesafety I lose when dealing with ActorRefs. 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

Answers (3)

simpadjo
simpadjo

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

dveim
dveim

Reputation: 3482

Promises won't work in distributed actor system.

At least, without additional efforts for that.

Upvotes: 1

Odomontois
Odomontois

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

Related Questions