加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – Akka TypedActor与将我自己的静态接口写入Actor类

发布时间:2020-12-16 09:48:07 所属栏目:安全 来源:网络整理
导读:我一直在使用Akka和Scala大约一个月,我有点困扰,用消息替换显式接口。考虑下面的简单Akka Actor: case class DoMyHomework()class Parent extends Actor { def receive = { case d: DoMyHomework = // do nothing }} 向此actor发送DoMyHomework消息的acto
我一直在使用Akka和Scala大约一个月,我有点困扰,用消息替换显式接口。考虑下面的简单Akka Actor:

case class DoMyHomework()
class Parent extends Actor {
  def receive = {
    case d: DoMyHomework => // do nothing
  }
}

向此actor发送DoMyHomework消息的actor或非actor代码,如下所示:

ActorRef parent = ...
parent.ask(DoMyHomework)

不知道结果会是什么。答案的类型是什么?我会得到答案吗?我可以得到一个例外吗?等等。

修复似乎是文档case类…但如果一些其他actor也接收到相同的case类。然后文档应该接收该消息应该在actor本身。

为了努力清理这一点,我想到了做以下事情:

trait SomeoneSmarter {
  def wouldYouDoMyHomework: Future[Boolean] 
}
class Parent extends Actor with SomeoneSmarter {
  case class DoMyHomework()
  def wouldYouDoMyHomework = {
    (self ? DoMyHomework()).mapTo(Boolean)
  }
  def receive = {
    case d: DoMyHomework =>
      // TODO: If I'm busy schedule a false "No way" reply for a few seconds from now.
      // Just to keep their hopes up for a while. Otherwise,say sure right away.
  }
}

所以,我和同事聊了一下,其中一个反应是“你不是真的对演员模型。

首先,我真的很感谢来自那些使用Actors更长时间的人的一些指导。所有的消息都变得笨重吗?你最终是否隐藏了接口后面的消息传递?

我提议的演员仍然可以选择在他们之间发送消息,订阅事件流,所有的东西,你希望从Akka。而且界面给你一个时间考验的方式知道你在说什么。它有助于在IDE中编码,等等。为什么一个演员的用户需要知道它是一个演员(除非它也是一个演员,并与它紧密耦合)?

我得到的另一个反应是“它看起来像你想要一个TypedActor”。但阅读TypedActor后,我不相信。当然TypedActor为我创造了这些内部消息的麻烦。但是,至少从代码示例中
http://doc.akka.io/docs/akka/snapshot/scala/typed-actors.html我得到这样的印象,TypedActor只是作为一个代理,你想要封装的代码块,或线程安全,或只是直接从你当前的线程调用。你所编写的代码只是实现和接口。你不会搞乱演员本身(代理) – 例如。如果您希望您的实现执行定期工作或订阅事件流,或执行与接口无关的其他任何操作。

我也读过http://letitcrash.com/post/19074284309/when-to-use-typedactors,没有发现这个例子更加明亮。我可能只是不是Grokking TypedActor(不是说我真的理解了Actors)。

感谢提前的帮助。

皮诺

解决方法

演员封装

让我先回应一点,我认为是很重要的。你说:

And why should the user of an actor need to know it’s an actor (unless it’s also an actor and is very tightly coupled with it)?

Actor是一个与传统OO完全不同的编程范例,主要的区别是一切都是异步的,因此从来没有真正的“返回值”。这意味着隐藏它是一个行为者的事实通常是一个坏主意,对于异常引用my TypedActors blog post.关于actors的最好的事情是他们完全封装在Akka后面ActorRef – 而不是弱封装OO语言。为了充分利用它,尽可能公开ActorRefs,这给客户端代码提供了以最合适的方式使用它们的机会(可能根据上下文使用tell或ask)。

结构化您的消息

当写一个actor时,你应该把这个actor的所有内容放在一个地方,包括接口契约描述。它可能看起来有点像这样:

object Parent {
  /**
   * Send this message to make your parent do your homework … yeah,right ;-)
   */
  case object DoHomework
}

/**
 * This actor will do your homework if asked to.
 * 
 * ==Actor Contract==
 * 
 * ===Inbound Messages===
 *  - '''DoHomework''' will ask to do the homework
 * 
 * ===Outbound Messages===
 *  - '''HomeworkResult''' is sent as reply to the '''DoHomework''' request
 * 
 * ===Failure Modes===
 *  - '''BusinessTripException''' if the parent was not home
 *  - '''GrumpyException''' if the parent thinks you should do your own homework
 */
class Parent extends Actor {
  …
}

与TypedActor的差异

使用正常的非类型的actor可以让你充分利用actor模型的全部功能,包括动态改变行为,而不是被诱惑进入超时保护笼中的“同步”调用(简而言之,TypedActors最常用于使用幕后演员实现传统的同步接口)。我同意IDE支持消息类型会很好,但这是一个工具问题(我一直在与ScalaIDE团队谈论添加一些魔法,但必须等待,直到它可以获得优先级)。具有关于在一个地方定义的actor的所有属性是重要的部分。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读