Simon Simon - 18 days ago 7
Scala Question

Is there a way to know the context of an Akka actor?

I have an actor with some contexts, i.e.

def step2: Receive = {
case _ => log error "Unhandled message"
}

def step1: Receive = {
case _ => log error "Unhandled message"
}


Is there a way to know on which state the actor currently is (step1, step2)?
(I could stock the value on a
string
but I wonder if there is a better way.)

If it not possible, I would like to understand why since this state should be kept somewhere.

Answer

FSM

You can use FSM. stateName gives the name of the state.

Ping the Actor with some special message handled in every state to send the stateName.

sealed trait ExampleState
case object State1 extends ExampleState
case object State2 extends ExampleState
case object C extends ExampleState

import akka.actor.{Actor, FSM}
import akka.event.EventHandler
import akka.util.duration._

case object Move

class ABC extends Actor with FSM[ExampleState, Unit] {

  import FSM._

  startWith(State1, Unit)

  when(State1) {
    case Ev(Move) =>
      EventHandler.info(this, "Go to B and move on after 5 seconds")
      goto(state2) forMax (5 seconds)
  }

  when(State2) {
    case Ev(StateTimeout) =>
      EventHandler.info(this, "Moving to C")
      goto(C)
  }

  when(C) {
    case Ev(Move) =>
      EventHandler.info(this, "Stopping")
      stop
  }

  initialize // this checks validity of the initial state and sets up timeout if needed
}

Hacky Solution

Akka Actor does not store any specific information about the PartialFunction. So I don't think there will be a akka lib function readily available for this.

Have state inside the actor and then update the state when Actor tries to become something.

class FooBar extends Actor with ActorLogging {

  var state: Option[String] = Some("receive")

  override def receive: Receive = {
    case _ => context become state1()
  }

  def state1: () => Receive = {
    () => {

      state = Some("state1")

      {
        case _ => log error "ignore"
      }
    }
  }


  def state2: () => Receive = {
    () => {

      state = Some("state2")

      {
        case _ => log error "ignore"
      }
    }
  }


}
Comments