5

How do I intercept a PartialFunction? e.g. in actors, if I'd like to just print everything that comes into the following receive method before passing it onto the process method:

class MyActor extends Actor {
  def receive : Receive = process
  def process : Receive = {
    case Some(x) => /* do one thing */ ()
    case None => /* do another thing */ ()
    case _ => /* do something else */ ()
  }
}
Jamie McCrindle
  • 9,114
  • 6
  • 43
  • 48
  • 1
    Related and possibly useful: The configuration property `akka.actor.debug.receive` can enable printing of every message received by any actor at DEBUG level. See config documentation for more info: http://doc.akka.io/docs/akka/2.2.3/general/configuration.html – Marius Danila Dec 17 '13 at 00:12
  • Duplicate of http://stackoverflow.com/questions/19827027/how-to-add-logging-function-in-sending-and-receiving-action-in-akka/19838821#19838821? – sourcedelica Dec 17 '13 at 01:44

3 Answers3

7

A PartialFunction is a trait that you can implement. You aren't forced to use the case syntax.

Unfortunately, it doesn't come with a convenient method for composing in the way you describe. The closest is the andThen method, but the argument you pass must be a regular function, which could lead to match errors when an argument is unhandled in the actual receive function. So you're stuck writing it the long way.

class MessageInterceptor(receiver: Receive) extends Receive {
  def apply(msg: Any) = {
    /* do whatever things here */
    receiver.apply(msg)
  }
  def isDefinedAt(msg: Any) = receiver.isDefinedAt(msg)
}

val process = new MessageInterceptor(receive)
Dylan
  • 13,645
  • 3
  • 40
  • 67
4
def process: Receive = printMessage andThen {
  case Some(x) => /* do one thing */ ()
  case None => /* do another thing */ ()
  case _ => /* do something else */ ()
}

def printMessage: PartialFunction[Any, Any] = {
  case m => 
    println(m)
    m
}
vptheron
  • 7,426
  • 25
  • 34
2

I suppose andThen method is a right choice:

def printEverything: PartialFunction[Any, Any] = {
case x =>
    println(x)
    x
}

and use it:

def receive : Receive = printEverything andThen process
maks
  • 5,911
  • 17
  • 79
  • 123