I have a trait and implementing akka actor that can't properly differentiate the types of incoming messages due to type erasure, and so the first case is matching all messages.
I'm using scala 2.10.x, and from reading many other answers I know that it is possible to recover type information inside a trait using TypeTag
or ClassTag
, but I can't figure out how to apply it (if it is possible) within the akka receive.
My (very simplified) example is as follows. Is it possible properly match the generic types?
package com.ebay.box.canada.batch.jobs.siteMap
import akka.actor.Actor
import akka.actor.ActorSelection
import akka.actor.Actor.Receive
import scala.reflect.ClassTag
trait MessageProcessor[A,B] {
this: Actor =>
val destA: ActorSelection
val destB: ActorSelection
def processA(a: A): A
def processB(a: B): B
def receive: PartialFunction[Any,Unit] = {
case a: A =>
destA ! processA(a)
case b: B =>
destB ! processB(b)
}
}
class StringIntProcessor(val destA: ActorSelection, val destB: ActorSelection) extends MessageProcessor[String,Int] with Actor {
def processA(a: String) = { a + "1" }
def processB(b: Int) = { b + 1 }
}
I don't think you can get at
TypeTag[A]
orClassTag[A]
in your trait -- type tags/class tags are always part of the implicit argument list to a method call. You might be able to use an abstract class instead, with implicit constructor arguments:(Not tested!)
Supposing that you can change the code that sends the message, can I suggest the following design instead? MessageProcessor is now a typeclass, so that you can add any number of message types. By sending a closure as the message, you can smuggle any amount of context into the call site.
(Also not tested!)