0

依赖replyScala Actor 对我来说似乎非常容易出错。这真的是在演员之间进行对话的惯用 Scala 方式吗?有没有替代方案,或更安全地使用reply我所缺少的?

(关于我:我熟悉 Java 中的同步,但我之前从未设计过基于 actor 的系统,也没有完全理解该范式。)

示例错误

作为一个简单的演示,让我们看看这个愚蠢的整数解析 Actor:

import actors._, Actor._

val a = actor {
  loop {
    react {
      case s: String => reply(s.toInt)
    }
  }
}

我们可以打算将其用作

scala> a !? "42"
res0: Any = 42

但是如果演员没有回复(在这种情况下,因为粗心的程序员没有想到要抓住NumberFormatException演员),我们将永远等待:

scala> a !? "f"

我们在呼叫现场也犯了一个错误。下一个示例也无限期阻塞,因为参与者不回复Int消息:

scala> a !? 42

超时

如果预期的回复有一些已知的合理时间限制,您可以使用!? (msec: Long, msg: Any),但在我能想到的大多数情况下,情况并非如此。

保证回复

一种想法是设计该actor,使其必须回复每条消息:

import actors._, Actor._

val a = actor {
  loop {
    react {
      case m => reply { 
        try {
          m match {
            case s: String => reply(s.toInt)
            case _ => None
          }
        } catch {
          case e => e
        }
      }
    }
  }
}

这样感觉好多了,虽然还是有点怕一不小心调用!?了一个演员不再演戏了。

4

3 回答 3

1

我自己并不熟悉 Scala 标准库中的 Actor 系统,但我强烈建议您查看 Akka 工具包 ( http://akka.io/ ),它已“替换”了 Scala Actors 并附带 Scala 发行版斯卡拉 2.10。

总体而言,在 Actor 系统设计方面,一些关键思想是异步(非阻塞)、隔离可变性和通过消息传递进行通信。每个 Actor 都封装了自己的状态,不允许其他任何人触摸它。您可以向 Actor 发送一条可能“要求”它更改状态的消息,但 Actor 实现可以随意忽略它。消息是异步发送的(你可以让它阻塞,不推荐)。如果您想要某种“响应”(以便您可以将消息与先前发送的消息关联),FutureScala 2.10 和askAkka 中的 API 可以提供帮助。

关于您的错误格式异常和一般问题,请考虑查看 Scala 2.10 和 Akka 2.1 中的askFutureAPI。它将处理异常并且是非阻塞的。

Scala 2.10 也有一个新Try的,旨在替代老式try-catch子句。Try有一个apply你会像任何一样使用的方法(try减去catchand finally)。Try有两个子类SuccessFailure。的实例Try[T]将具有子类Success[T]Failure[Throwable]. 通过示例更容易解释:

>>> val x: Try[Int] = Try { "5".toInt } // Success[Int] with encapsulated value 5
>>> val y: Try[Int] = Try { "foo".toInt } // Failure(java.lang.NumberFormatException: For input string: "foo")

由于Try不会抛出实际异常并且子类是方便的案例类,因此您可以轻松地将结果用作给 Actor 的消息。

于 2013-01-03T20:17:50.630 回答
1

我可以看到你的担忧,但我实际上认为这并不比你习惯的同步更糟糕。谁保证锁会再次被释放?

使用!?风险自负,所以没有我知道的“更安全”的用途。线程可以阻塞或死亡,我们绝对无能为力。除了提供可以减轻打击的安全阀。

基于事件的行为实际上为您提供了同步接收回复的替代方案。超时是其中之一,但另一件事,例如通过该方法的Futures 。!!它们旨在处理诸如此类的死锁。该方法立即返回可以稍后处理的未来。

有关灵感和更深入的设计决策,请参阅:

演员: http ://docs.scala-lang.org/overviews/core/actors.html

期货(在 scala 2.10 中): http ://docs.scala-lang.org/sips/pending/futures-promises.html

于 2013-01-03T20:19:19.990 回答
1

Don't bother with old local actors - learn Akka. Also it's good that you know about synchronized, but personally me - almost never use such a word, even in Java code. Imagine synchronized is deprecated, learn Java memory model, learn CAS.

于 2013-01-03T20:28:26.503 回答