Will I Am Will I Am - 1 year ago 57
Scala Question

Sequence of actor ask calls

Suppose I have the following actor:

class A extends Actor {
def receive = {
case Unlock => sender ! UnlockResponse (Boolean_code)
case Read => sender ! ReadResponse (somedata)
case Lock => sender ! LockResponse (Boolean_code)
} }

I would like to write.a helper method where I can call unlock, read, and lock sequentially, and return the "somedata" from the ReadResponse to the method caller after last step (lock) has completed.

I like the for-comprehension approach, but how do I write it with a bit more flexibility, for example to continue to Read only if Unlock returns UnlockResponse(true) in the first step, but abort if the return is UnlockResponse(false)?

Answer Source

For the sequential logic you could use Scala Promises api:

val promise = Promise[ReadResponse]()
val unlockFuture = anActorRef ? Unlock
val readFuture = anActorRef ? Read
   case UnlockResponse (true) => promise.completeWith(readFuture)
   case UnlockResponse (false) => p.failure(new IllegalStateException)

and then depending on the outcome you can do something like

p.future.onComplete {
  case Success(somedata) => {
      anActorRef ! Lock
  case Failure(t) => logger.error(t)

A more elegant solution with the same sequential effect could be achieved via the Actor become/unbecome and stash, where the transaction logic is handled by the actor itself instead of the sender.