如何在akka中扩展超级演员的行为

Posted

技术标签:

【中文标题】如何在akka中扩展超级演员的行为【英文标题】:How extend behaviour of super actor in akka 【发布时间】:2017-09-29 07:29:28 【问题描述】:

我想使用 akka actor 实现 CRUD 操作。我是akka新手,所以不知道akka actor的设计基础。

我想在多个子actor中分享akkaactor的行为。

我想保存和删除学生、教师和其他实体的示例。

我为 StudentDao.scala 创建了actor

class StudentDao extends Actor with ActorLogging

 override def Receive = 

    case Add(student) =>
      // Add to database
    case Delete =>
      //Delete from database     
   // Some other cases related to Student entity
  

case object StudentDao
  case class Add(user : Student)
  case class Delete(id : String)

我也有 TeacherDao.scala 的演员

class TeacherDao extends Actor with ActorLogging

 override def Receive = 

    case Add(teacher) =>
      // Add to database
    case Delete =>
      //Delete from database      
    // Some other cases related to teacher entity

  
 

object TeacherDao
  case class Add(user : teacher)
  case class Delete(id : String)

我想为两个 dao 抽象删除方法。 所以我创建了 BaseDao.scala

class BaseDao extends Actor with ActorLogging

  override def Receive = 

    case Delete =>
      //Delete from database   dao.delete
  

如何使用基本actor进行抽象。

【问题讨论】:

【参考方案1】:

orElse 是扩展actor 行为的方式,因为actor 的Receive 只是PartialFunction[Any, Unit] 的别名。下面是您的用例的具体说明。

首先,在必须与参与者混合的特征中定义基本行为。为避免重复,请将 Delete 案例类移动到此 trait 的伴随对象中。

trait BaseDao  this: Actor with ActorLogging =>
  import BaseDao._

  def baseBehavior: Receive = 
    case Delete(id) =>
      log.info(s"Deleting $id from db")
      // delete from db
  


object BaseDao 
  case class Delete(id: String)

然后,将上述特征混合到您的其他参与者中,并将这些行为与orElse 链接起来。请注意,我创建了虚拟 StudentTeacher 案例类,以便可以编译此代码。 StudentDao:

class StudentDao extends Actor with ActorLogging with BaseDao 
  import StudentDao._

  def studentBehavior: Receive = 
    case Add(student) =>
      log.info(s"Adding student: $student")
    // some other cases related to Student
  

  def receive = studentBehavior orElse baseBehavior


object StudentDao 
  case class Add(user: Student)

case class Student(name: String)

还有TeacherDao:

class TeacherDao extends Actor with ActorLogging with BaseDao 
  import TeacherDao._

  def teacherBehavior: Receive = 
    case Add(teacher) =>
      log.info(s"Adding teacher: $teacher")
    // some other cases related to Teacher
  

  def receive = teacherBehavior orElse baseBehavior


object TeacherDao 
  case class Add(user: Teacher)

case class Teacher(name: String)

【讨论】:

【参考方案2】:

您可以为基础actor创建一个特征,使用一个公共接收函数orElse另一个必须在子actor中实现的函数:

trait BaseActor extends Actor 

  override def receive: Receive = commonReceive orElse handleReceive

  def commonReceive: Receive = 
    case CommonMessage => // do something
  

  def handleReceive: Receive

然后你的子actor只需要实现handleReceive:

class SubActor extends BaseActor 

  override def handleReceive: Receive = 
    case SpecificMessage => // do something
  

【讨论】:

以上是关于如何在akka中扩展超级演员的行为的主要内容,如果未能解决你的问题,请参考以下文章

如何在非对称系统中将对象发送到远程 akka 演员

Akka演员(Scala)如何在内存不足时获得堆转储[重复]

akka http:Akka 流与演员建立休息服务

如何访问通过 guice 创建的 akka 系统?

Akka & Java - 遇到死信

context.become 改变了 Akka Actor 的行为