我对akka actor系统还很陌生,并且一直在徘徊在actor中执行通用逻辑的最佳实践。 所以这是一个例子:

我有以下演员:

class MyActor @Inject()(eventBus: EventBus) extends Actor{
    eventBus.subscribe(context.self, Topics.TimeoffPolicy)
    override def receive: Receive = {
       case Foo(name:String) => {
           //Need to execute foo related logic, and then Bar related logic
       }
       case Bar(name:String) => {
             //Need to execute bar related logic
       }
       case a: Any => log.warning(f"unknown message actor ${a.toString}")
    }
}

因此,一种选择是将通用逻辑提取到方法中,并在像这样处理Foo时调用它:

class MyActor @Inject()(eventBus: EventBus) extends Actor{
    eventBus.subscribe(context.self, Topics.TimeoffPolicy)
    override def receive: Receive = {
       case Foo(name:String) => {
           foo(name)
           bar(name)
       }
       case Bar(name:String) => {
           bar(name)
       }
       case a: Any => log.warning(f"unknown message actor ${a.toString}")
    }
}

另一种选择是向自己发送消息:

class MyActor @Inject()(eventBus: EventBus) extends Actor{
    eventBus.subscribe(context.self, Topics.TimeoffPolicy)
    override def receive: Receive = {
       case Foo(name:String) => {
           foo()
           self ! Bar(name)
       }
       case Bar(name:String) => {
           bar(name)
       }
       case a: Any => log.warning(f"unknown message actor ${a.toString}")
    }
}

在这里,发送一条消息并在每次消息处理中保持逻辑封装是有意义的,但是我猜想将通用逻辑提取到方法中并调用它的错误处理较少。 推荐什么?

对于参与者之间的通用逻辑,情况也是如此,一种选择是通过事件总线将消息发送给另一参与者以进行调用,因此actor1将执行foo,而另一个将执行bar。 第二种选择是将相同的逻辑提取到另一个类中,并将该类注入两个参与者,因此,为了执行foo和bar,参与者之间将没有通信。

你怎么看?

===============>>#1 票数:1 已采纳

这两种方法在我看来都是合法的,我会根据是否在共享逻辑内调用其他角色来选择这两种方法之一。 基本上,同步逻辑可以通过提取方法来完美地重用,而异步逻辑则需要将消息传递回自身。

肯定也更希望从Future回调(实际上,这是唯一的正确方法,以便不干扰参与者任务的执行顺序)中发送self消息,并在计划的活动中发送。

以下是说明同步方法的代码段:

class MyActor extends Actor with ActorLogging {
  def receive = {
    case Foo(foo) =>
      doSomeFooSpecificWork()
      logFooOrBar()
      sender() ! "foo done"
    case Bar =>
      logFooOrBar()
      sender() ! "bar done"
  }

  def logFooOrBar() = log.debug("A common message is handled")
}

这是我为异步代码编写的内容:

import akka.pattern.{ask, pipe}
class MyActor extends Actor {
  val logger = context.actorOf(Props[DedicatedLogger])
  def receive = {
    case Foo(foo) =>
      doSomeFooSpecificWork()
      loggerActor ? LogFooOrBar(sender(), foo) pipeTo self

    case Bar(bar) =>
      loggerActor ? LogFooOrBar(sender(), bar) pipeTo self

    case LoggedFoo(reportTo, foo) => reportTo ! "foo done"

    case LoggedBar(reportTo, bar) => reportTo ! "bar done"
  }
}

  ask by Tomer translate from so

未解决问题?本站智能推荐: