【问题标题】:Confusion over Akka Actors vs Java ObjectsAkka Actor 与 Java 对象的混淆
【发布时间】:2013-04-11 12:58:35
【问题描述】:

我正在尝试让自己熟悉 Akka 和 Actors,但我认为我漏掉了一点。我的接收循环变得过大。例如:

class Node extends Actor {
  def receive {
    case "pause" => pause
    case "resume" => resume
    case "methodX" => methodX
    case "methodY" => methodY
    case "methodZ" => methodZ
  } 
}

我是 Actor、Scala 和函数式编程的新手。我认为我在对象领域的经验正在泄漏到我的演员定义中,所以我的问题是寻找有关如何以“正确”方式定义演员 API 并避免这种无类型消息爆炸的指导。

【问题讨论】:

    标签: design-patterns akka actor


    【解决方案1】:

    有多少消息都取决于您要封装的内容。一个好的规则是尽量让参与者专注于一项任务,然后让它将事情委托给其他参与者(从而使界面变小)。此外,使参与者无状态并在您发送的消息中包含状态将有很大帮助。

    保持消息不可变很重要,但这并不意味着它们必须是字符串。您可以定义您接受的消息,并使用案例类发送(以获得不变性),如果您使它们扩展密封特征,则让编译器为您做一些检查。这是一个示例,编译器会抱怨您的匹配不是详尽的,因为您没有在接收中处理 FooMessage。

    object MyActor {
      // these are the messages we accept
      sealed abstract trait Message
      case class FooMessage(foo: String) extends Message
      case class BarMessage(bar: Int) extends Message
    
      // these are the replies we send
      sealed abstract trait Reply
      case class BazMessage(foo: String) extends Reply
    }
    
    class MyActor extends Actor {
      import MyActor._
      def receive = {
        case message: Message ⇒ message match {
          case BarMessage(bar) => sender ! BazMessage("Got " + bar)
        }
      }
    }
    

    您还应该尝试在火灾中考虑演员并在此期间做一些其他事情(火灾并忘记声音太刺耳)。那就是你应该使用告诉(!)而不是问(?)。不要将消息发送视为方法调用。这将使您的代码阻塞而不是扩展。

    actor 使用的一个常见示例是有一个actor 链,其中每个actor 执行一项任务,然后将转换后的消息转发给下一个actor。最后,您回复启动链的参与者,或者他说您应该回复的任何人,从而缩短中间的所有参与者。消息无需向下传播,然后再备份链。

    希望这能给你一些想法。

    【讨论】:

    • 感谢您花时间回答。重新“使演员无国籍” - 如果不能保证消息传递,这怎么是个好主意? (顺便说一句,我正在使用 remoteactors,所以不交付是一个问题)。我喜欢关于密封特征的观点,这非常有用。关于actor链的一点很有趣——它听起来像是一个actor特定的设计模式。也许我可以在某个地方找到这些列表
    猜你喜欢
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2012-05-21
    • 2015-06-26
    • 2012-03-04
    • 2011-03-04
    • 1970-01-01
    • 2019-12-19
    相关资源
    最近更新 更多