0

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

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

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

4

1 回答 1

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。最后,您回复启动链的参与者,或者他说您应该回复的任何人,从而缩短了中间的所有参与者。消息无需向下传播,然后在链上进行备份。

希望这能给你一些想法。

于 2013-04-12T07:41:42.793 回答