2

我正在尝试同时学习 Scala 和 Akka,这很棒,但有时也有点令人困惑,我很抱歉我的问题不完整。

我了解演员模型。有演员,他们发送和接收消息,他们有一个邮箱来存储收到的消息,邮箱可以优先处理消息,然后一切都变得混乱。

我读了很多书,越读越困惑,所以我希望有人能提供一些帮助,将困惑程度降低到可接受的最低限度。欢迎指点,但我可能需要一些小的胶水解释来把所有东西放在一起,基本上对 RTFM 有一些帮助。

问题是:

  1. 如何在收件箱中对邮件进行排序?我读过“隐含”(在有序邮箱中),但这听起来很神奇。我认为排序邮箱只会接受实现Comparable接口的类型,但这里 Scala 使用函数范式并接受一个ordering函数,如果我没记错的话,它会返回一个Ordering[T]. 然而,排序函数(在T? 上工作)可能仅限于可比较的对象,所以,回到Comparable?
  2. 有没有可能共享邮箱?
  3. 是否应该在这里使用总线的某些实现?公交车可以分拣吗?
  4. 什么是implicit abstract def? 它看起来像一个应该实现的方法(abstract)但不需要实现(implicit),这听起来很矛盾。(这是 中的定义SortedSet
  5. 我应该定义一个Dispatcher吗?我一直无法弄清楚它在整个架构中是如何匹配的。但我一直在寻找池和寻找调度员。
  6. 我应该阅读关于Futures 的内容吗?我正在尝试做一个小的实现来逐步掌握概念,在阅读和编程的循环中。再次为这么多问题感到抱歉。

到目前为止,我认为的解决方案包括:

  1. 有一个作为通信中心节点的 Actor。
  2. 这个中央 Actor 保留了一个SortedSet将发送到 Actor 池的消息排队的位置
  3. 这个中心 Actor 还保留了一个Set免费的 Actor。
  4. 当一个 Actor 空闲时(在处理任何消息之后),空闲 Actor 会向中心 Actor 发送一条消息,要求做一些工作。
  5. 中心参与者处理消息:
    1. 如果有待处理的工作,它会将需要处理的消息出列。
    2. 如果没有工作要做,则存储对自由球员的引用以向他发送一些工作。
  6. 中心参与者以类似的方式处理带有作业任务的消息。
    1. 如果有自由演员,那么工作将被发送给自由演员。
    2. 如果没有免费演员,则该工作将添加到SortedSet.
  7. 演员池是通过简单地创建它们并将它们的所有引用发送给中央管理器来创建的。

我想到了这个解决方案,因为我对 Scala 和 Akka 不太了解。但我不想永远被这种类型的解决方案所困。基本上演员可以做任何事情,但我想正确使用它们并正确使用所有其他元素,如邮箱、总线、池、调度程序、期货等。

非常感谢。

4

1 回答 1

2
  • 1 & 2 & 5:Akka 关于调度程序的文档很好地解释了调度程序是什么以及如何定义和使用调度程序。它还记录了邮箱、如何定义自己的、可能优先考虑的邮箱以及多个参与者如何共享一个邮箱: http ://doc.akka.io/docs/akka/2.1.4/java/dispatchers.html

  • 3:AFAIK,EventBusAkka默认的,不允许排序消息

  • 4:implicit abstract def定义了一个abstract也是implicit. 隐式和抽象成员是正交的概念,所以这里没有矛盾。也许您想定义一个隐式转换并将其实现委托给子类。

  • 6:是的,future 是一个重要的部分,不仅在 Akka 中,而且对于一般的 Scala 并发来说也是如此。

关于您的特定设计问题,也许更简单的解决方案是使用路由器。路由器是根据策略将传入消息发送到其注册路由的特殊参与者。

http://doc.akka.io/docs/akka/2.1.4/scala/routing.html

在您的情况下,您将用路由器替换您的中心角色。如果您的邮件需要优先处理,您可以为该路由器配置一个优先邮箱。

接近您描述的行为的路由器将是SmallestMailboxRouter

如果你确实决定需要使用一个中央actor来积累消息,那么在监督这个actor时要格外小心。默认情况下,失败的参与者会重新启动,因此您最终可能会丢失SortedSet保存您的消息的参与者。这是使用自定义邮箱的另一个原因:您将参与者状态与消息排序语义解耦。

于 2013-06-06T09:08:53.863 回答