Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to always call a method inside receive() even if nothing matches

Tags:

scala

akka

I am fairly new to the Akka/Scala world. I am trying to figure out what is the best way of having something always executed when an actor is receiving a message even if there is no match for it. I know that receive is PartialFunction but I was wonder if there is a better way of doing this than:

def receive: Receive = {
  case string: String => { 
    functionIWantToCall()
    println(string)
  }
  case obj: MyClass => {
    functionIWantToCall()
    doSomethingElse()
  }
  case _ => functionIWantToCall()
}

I am pretty sure there is a better way in Scala for doing this instead of calling functionIWantToCall() inside each case. Can somebody suggest something :)?

like image 472
hveiga Avatar asked Feb 11 '23 16:02

hveiga


1 Answers

You can wrap your Receive function in "higher-order" Receive function

  def withFunctionToCall(receive: => Receive): Receive = {
    // If underlying Receive is defined for message
    case x if receive.isDefinedAt(x) =>
      functionIWantToCall()
      receive(x)

    // Only if you want to catch all messages
    case _ => functionIWantToCall()
  }

  def receive: Receive = withFunctionToCall {
    case string: String => println(string)
    case obj: MyClass => doSomethingElse()
  }

Or you can read about Pipelines in Akka docs: http://doc.akka.io/docs/akka/snapshot/contrib/receive-pipeline.html

I think it's exactly what you need for this type of problem

  val callBefore: Receive => Receive =
    inner ⇒ {
      case x ⇒ functionIWantToCall; inner(x)
    }

  val myReceive: Receive = {
    case string: String => println(string)
    case obj: MyClass => doSomethingElse()
  }

  def receive: Receive = callBefore(myReceive)
like image 163
Eugene Zhulenev Avatar answered May 04 '23 00:05

Eugene Zhulenev