为什么我应该使用context.become()在Actor中存储内部状态? [英] Why I should use context.become() to store internal state in Actor?

查看:107
本文介绍了为什么我应该使用context.become()在Actor中存储内部状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读 scala-best -惯例,并有一个关于 5.2。应该仅使用context.become改变演员中的状态的问题。我不明白为什么使用 var 存储内部状态如此糟糕。如果actor按顺序执行所有消息,我将看不到任何问题根源。我想念什么?

I've read scala-best-practices and have a question about "5.2. SHOULD mutate state in actors only with context.become". I don't understand why it is so bad to store internal state using var. If actor executes all messages sequentially I just can't see any source of problems. What do I miss?

推荐答案

请考虑文章引用:

class MyActor extends Actor {
  val isInSet = mutable.Set.empty[String]

  def receive = {
    case Add(key) =>
      isInSet += key

    case Contains(key) =>
      sender() ! isInSet(key)
  }
}

此示例没有内在的错误,因此您并没有一些重要的认识。如您所知,actor会顺序处理其邮箱中的消息,因此 可以安全地在内部变量中表示其状态并对该状态进行突变,只要actor不会 1

There's nothing inherently incorrect with this example, so there isn't some vital understanding that you're missing. As you know, an actor processes the messages in its mailbox sequentially, so it is safe to represent its state in an internal variable and to mutate this state, as long as the actor doesn't expose that state1.

成为通常用于动态切换角色的行为(例如,更改角色处理的消息的类型)和/或其状态。在本文的第二个示例中,演员的状态以其行为编码为参数。这是第一个示例的一种很好的替代方法,但是在这种简单的情况下,这只是一个优先选择的问题。

become is often used to dynamically switch an actor's behavior (e.g., changing the kind of messages that the actor handles) and/or its state. In the second example in the article, the actor's state is encoded in its behavior as a parameter. This is an elegant alternative to the first example, but in this simple case it's a matter of preference.

出现 确实可以发光,但是,它是一个具有许多状态转换的参与者。如果不使用成为,则演员在其 receive 块中的逻辑会变得难以控制地变大,或者变成 if-else 语句。作为使用 become 为状态转换建模的示例,请查看此示例项目,用于对餐厅哲学家 问题。

One scenario in which become can really shine, however, is an actor that has many state transitions. Without the use of become, the actor's logic in its receive block can grow unmanageably large or turn into a jungle of if-else statements. As an example of using become to model state transitions, check out this sample project that models the "Dining Philosophers" problem.

1 一个潜在的问题是 isInSet val ,它是一个可变的 Set ,因此,如果actor将这种状态暴露给actor本身之外的东西,则可能会发生怪异的事情(在示例中未这样做) 。例如,如果演员在一条消息中将此 Set 发送给另一个演员,则外部演员会更改此状态,从而导致意外的行为或竞赛条件。可以通过将 val 更改为 var ,并将可变的Set更改为不可变的<$ c $来缓解此问题。 c>设置。

1A potential issue is that while isInSet is a val, it's a mutable Set, so weird things can happen if the actor exposes this state to something outside of the actor itself (which it is not doing in the example). For example, if the actor sends this Set in a message to another actor, then the external actor can change this state, causing unexpected behavior or race conditions. One can mitigate this issue by changing the val to a var, and the mutable Set to an immutable Set.

这篇关于为什么我应该使用context.become()在Actor中存储内部状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆