Reputation: 53806
Below code :
package playground
import akka.actor.{Actor, ActorRef, ActorSystem, Props, _}
import akka.stream.ActorMaterializer
case object ReplyMessage
case object StopMessage
case object LinRMessage
case object LinRMessageChild
case class ListData(data : List[String])
class ModelParent(child: ActorRef) extends Actor {
val logger = com.typesafe.scalalogging.Logger("ModelParent")
def receive = {
case ListData =>
logger.info("Got reply in Parent")
case LinRMessage =>
child ! LinRMessageChild
case _ => println("Parent got something unexpected.")
}
}
class ModelChild extends Actor {
val logger = com.typesafe.scalalogging.Logger("ModelChild")
def receive = {
case LinRMessageChild =>
logger.info("Received LinRMessage")
//sender ! ReplyMessage
val l = List("1" , "2" , "3")
sender ! ListData(l)
case StopMessage =>
println("Received Stop Message")
context.stop(self)
case _ => println("Child got something unexpected.")
}
}
object ModelsDriver {
def main(args: Array[String]): Unit = {
val system = ActorSystem("sys")
implicit val materializer = ActorMaterializer.create(system)
val modelChild = system.actorOf(Props[ModelChild], name = "modelChild")
val modelParent = system.actorOf(Props(new ModelParent(modelChild)), name = "modelParent")
modelParent ! LinRMessage
modelParent ! LinRMessage
modelParent ! LinRMessage
}
}
prints to console :
22:08:55.807 [sys-akka.actor.default-dispatcher-2] INFO ModelChild - Received LinRMessage
22:08:55.810 [sys-akka.actor.default-dispatcher-2] INFO ModelChild - Received LinRMessage
22:08:55.810 [sys-akka.actor.default-dispatcher-2] INFO ModelChild - Received LinRMessage
Parent got something unexpected.
Parent got something unexpected.
Parent got something unexpected.
Here is causing the Parent got something unexpected.
output :
case _ => println("Parent got something unexpected.")
I'm attempting to return a List of Strings from the child to the parent actor of type :
case class ListData(data : List[String])
This populates the return data :
val l = List("1" , "2" , "3")
sender ! ListData(l)
But as error indicates I'm not sending the data correctly. How to send data within message between a parent and child actor ?
Upvotes: 1
Views: 208
Reputation: 48410
When we define a case class
case class Foo(x: Int)
the compiler also automatically defines the corresponding companion singleton object
object Foo {
def apply(x: Int): Foo = new Foo(x)
def unapply(v: Foo): Option[Foo] = ...
}
Hence the function
val recieve: Any => String = {
case Foo => "I am companion singleton object of Foo"
case Foo(_) => "I am instance of Foo case class"
}
recieve(Foo)
recieve(Foo(42))
outputs
res0: String = I am companion singleton object of Foo
res1: String = I am instance of Foo case class
where we see
case Foo => "I am companion singleton object of Foo"
matches on the automatically generated companion singleton object.
Similarly,
val recieve: Any => String = {
case _: Foo.type => "I am companion singleton object of Foo"
case _: Foo => "I am instance of Foo case class"
}
recieve(Foo)
recieve(Foo(42))
outputs
res0: String = I am companion singleton object of Foo
res1: String = I am instance of Foo case class
because they type of singleton object Foo
is Foo.type
, whilst the type of the instance Foo(42)
is Foo
. Also consider
val a: Foo = Foo(42)
val b: Foo.type = Foo
This logic error was introduced due to the presence of Any
in Any => Unit
. On the other hand, Foo => Unit
would catch the error at compile time
val recieve: Foo => Unit = {
case Foo => // compiler error: pattern type is incompatible with expected type
}
Upvotes: 3
Reputation: 22477
The problem is due to these lines in your parent actor:
case ListData =>
logger.info("Got reply in Parent")
Normally, you'd want to pattern match and extract the contents of the case class like so:
case ListData(l: List[String]) =>
logger.info("Got reply in Parent")
Where you'd be able to access the contents as l
.
Since in your example, you aren't really doing anything with the contents, you could do one of the following as well:
case ListData(_) =>
logger.info("Got reply in Parent")
or:
case _: ListData =>
logger.info("Got reply in Parent")
Upvotes: 4