0

Scala Actor のa に依存すると、reply信じられないほどエラーが発生しやすいように思えます。これは本当に、アクター間で会話を行うための Scala の慣用的な方法ですか? reply私が見逃している別の方法、またはより安全な使用方法はありますか?

(私について: Java での同期には精通していますが、アクター ベースのシステムを設計したことがなく、パラダイムを完全に理解していません。)

間違いの例

簡単なデモとして、このばかげた整数解析アクタを見てみましょう。

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)予想される応答に妥当な時間制限があることがわかっている場合に使用できますが、私が考えることができるほとんどの状況ではそうではありません。

返信保証

考えられるのは、すべてのメッセージに必ず応答するようにそのアクターを設計することです。

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 標準ライブラリのアクター システムには詳しくありませんが、Scala アクターを「置き換え」、現在の Scala ディストリビューションに付属している Akka ツールキット ( http://akka.io/ ) を確認することを強くお勧めします。スカラ 2.10。

アクター システムの設計全般に関して言えば、重要なアイデアのいくつかは、非同期 (ノンブロッキング)、分離された可変性、およびメッセージ パッシングによる通信です。各アクターはそれ自身の状態をカプセル化し、他の誰もそれに触れることはできません。アクターに状態の変更を「要求」するメッセージを送信できますが、アクターの実装はそれを自由に無視できます。メッセージは非同期に送信されます (ブロックすることはできますが、お勧めしません)。何らかの「応答」が必要な場合 (メッセージを以前に送信されたメッセージに関連付けることができるようにするため)、FutureScala 2.10 およびaskAkka の API が役立ちます。

エラー形式の例外と一般的な問題については、Scala 2.10 と Akka 2.1 のaskAPIFutureを参照してください。例外を処理し、ノンブロッキングです。

Scala 2.10 には、Try旧式のtry-catch節に代わるものとして意図された新しい節もあります。にTryは、他のapplyものと同じように使用するメソッドがありますtry(catchおよび を除くfinally)。Tryには と の 2 つのサブクラスがSuccessありFailureます。のインスタンスに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サブクラスは便利なケースクラスであるため、結果をアクターへのメッセージとして簡単に使用できます。

于 2013-01-03T20:17:50.630 に答える
1

あなたの懸念はわかりますが、実際には、これはあなたが慣れ親しんでいる同期よりも悪くないと主張します. ロックが再び解放されることを誰が保証しますか?

使用!?は自己責任であるため、私が認識している「より安全な」使用法はありません。スレッドはブロックまたは停止する可能性があり、それに対して私たちができることはまったくありません。打撃を和らげることができる安全弁を提供することを除いて。

イベントベースの動作は、応答を同期的に受信する代わりの方法を実際に提供します。タイムアウトはその 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 に答える