How to get around erasing styles with the Akka method

I use the cake template in Scala 2.10 to introduce the required trait to my actor according to some business logic:

I have several types of f Events:

sealed abstract class Event(val timeStamp:Long) case class StudentEvent(override val timeStamp:Long, studentId:Long) extends Event(timeStamp:Long) case class TeacherEvent(override val timeStamp:Long, teacherIdId:Long) extends Event(timeStamp:Long) 

Now I have traits that implement an action for each type of event:

Annotation:

 trait Action[T <: Event] { def act[T](event:T):Unit } 

And two implants:

 trait StudentAction extends Action[StudentEvent]{ override def act[StudentEvent](event:StudentEvent):Unit = println(event) } 

and

 trait TeacherAction extends Action[TeacherEvent]{ override def act[TeacherEvent](event:TeacherEvent):Unit = println(event) } 

Now my actor:

 class ActionActor[T <: Event] extends Actor{ self:Action[T]=> override def receive= { case msg: T => act(msg) case _ => println("Unknown Type") } } 

And I enter the required trait as follows:

  val actionActor = system.actorOf(Props(new ActionActor[StudentEvent] with StudentAction)) actionActor ! StudentEvent(1111L,222L) 

When compiling, I get an error message:

 Warning:(14, 14) abstract type pattern T is unchecked since it is eliminated by erasure case msg:T => act(msg) ^ 

I know that for some reason I need to use TypeTag, but I did not understand how to do this.

Please, help.

Update:

In fact, I have 10 types of events that extend from the event I need to handle.

I want to implement the business logic for each event in a separate attribute, because since mixing all 10 functions of the event handler will give me several hundred (if not thousands) lines of code.

I do not want to create different types of Actor for each event. For instance:

 class Event1Actor extend Actor{ def receive ={ case Event1(e) => //event1 Business Logic } } class Event2Actor extend Actor{ def receive ={ case Event2(e) => //event2 Business Logic } } 

the same Event3Actor, Event4Actor, etc.

Such code seems ugly to me because I need to implement business logic within each Actor.

I am looking for some general solution based on a design pattern, for example, a strategy pattern.

+2
source share
1 answer

First, I would suggest defining your events as:

 sealed trait Event { def timeStamp: Long } case class StudentEvent(timeStamp: Long, studentId: Long) extends Event case class TeacherEvent(timeStamp: Long, teacherId: Long) extends Event 

This is the standard encoding for algebraic data types.

Secondly, this business in which you use the homing seems to me very confusing. Surely the same object should not be an "actor" and an "action"? Why not use composition here instead of inheritance? (It seems you are just throwing away Scala functions. So the general tip here is: slow down.)

But to solve your basic question, I think you are fundamentally wrong. Almost every time you end up with a head that TypeTag styles and / or TypeTag , this is a sign that your design is flawed and you should back up and rethink it if you don’t know what you are doing.

In any case, you cannot force Akka to attach TypeTag to your posts. Akka just doesn't work. (A series of efforts has been made to add "typed actors" or "typed channels" to Akka, and you can watch them, but this will probably be unnecessary in your use case if you are not sure if that is not the case.)

What is the main architecture problem you are trying to solve here? What motivated this design?

Check out By comparing the behavior of the trait in Scala with Akka's receiving method , it seems very similar, and after digesting it, I think you will be in a better position to decide what to do next.

+7
source

Source: https://habr.com/ru/post/982036/


All Articles