2

クライアントが要求するたびに何らかの作業を行うscalaアクターがあります。クライアントがアクティブでない場合にのみ、アクタにバックグラウンド処理を実行させたいと考えています。

これを行う最も簡単な方法は何ですか? 私は2つのアプローチを考えることができます:

  1. タイムアウトしてアクターを定期的にウェイクアップする新しいスレッドを生成します。単純なアプローチですが、別のスレッドを作成することは避けたいと思います (余分なコード、複雑さ、オーバーヘッドを避けるため)。

  2. Actor クラスには、actor 自体からのタイムアウトに使用できる reactWithin メソッドがあります。しかし、ドキュメントには、メソッドが返されないと書かれています。だから、私はそれを使用する方法がわかりません。

編集; 説明:

バックグラウンド タスクは、個別に処理できる小さな単位に分割できると仮定します。

4

3 に答える 3

6

わかりました、2 セントを投入する必要があることがわかりました。著者の回答から、ここで必要なのは「優先受信」テクニックだと思います。「 Erlang: priority receive question here at SO 」で議論を見つけることができます。優先度の高いメッセージを最初に受け入れ、優先度の高いメッセージがない場合にのみ他のメッセージを受け入れるという考え方です。

Scala アクターは Erlang に非常に似ているため、これを実装する簡単なコードは次のようになります。

def act = loop {
  reactWithin(0) {
    case msg: HighPriorityMessage => // process msg
    case TIMEOUT =>
      react {
        case msg: HighPriorityMessage => // process msg
        case msg: LowPriorityMessage => // process msg
      }
  }
}

これは次のように機能します。アクターには、メッセージを含むメールボックス (キュー) があります。(receiveまたはreceiveWithin) 引数は部分関数であり、アクター ライブラリは、この部分関数に適用できるメールボックス内のメッセージを探します。私たちの場合、それはHighPriorityMessageonly のオブジェクトになります。したがって、アクター ライブラリがそのようなメッセージを見つけた場合、部分関数が適用され、優先度の高いメッセージが処理されます。それ以外の場合はreactWithin、タイムアウト 0 で引数を指定して部分関数を呼び出し、TIMEOUTすぐにキューから可能なメッセージを処理しようとします (メッセージを待機するため、 get の可能性を除外することはできませんHighPriorityMessage)。

于 2009-10-14T08:45:13.210 に答える
2

あなたが説明した問題は、アクター サブシステムにはあまり適していないようです。Actorは、メッセージ キューを順次処理するように設計されています。

  • アクターがバックグラウンド作業を実行しているときに、新しいタスクが到着した場合はどうなりますか?

mailboxアクターは、バックグラウンド タスクを実行する際に継続的にチェックしている場合にのみ、これを知ることができます。これをどのように実装しますか (つまり、バックグラウンド タスクを作業単位としてどのようにコーディングして、攻撃者がメールボックスに割り込んでチェックし続けることができるようにしますか)。

  • アクターがメイン タスクの前のメールボックスに多くのバックグラウンド タスクを持っている場合はどうなるでしょうか?

これらのバックグラウンド タスクは破棄されますか、それとも別のアクターに送信されますか? 後者の場合、タスクを実行するためにそのアクターに CPU 時間が与えられないようにするにはどうすればよいでしょうか?

全体として、バックグラウンドで実行できるグリッド スタイルのソフトウェア (Data Synapse など) を探索する必要があるように思えます。

于 2009-10-13T14:20:50.440 に答える
2

この質問をした直後に、完全に奇抜なコードを試してみましたが、うまくいくようです。そこに落とし穴があるかどうかはわかりません。

import scala.actors._

object Idling

object Processor extends Actor {
  start

  import Actor._

  def act() = {
    loop {

      // here lie dragons >>>>>
      if (mailboxSize == 0) this ! Idling
      // <<<<<<

      react {
        case msg:NormalMsg => {
          // do the normal work
          reply(answer)
        }

        case Idling=> {
          // do the idle work in chunks
        }

        case msg => println("Rcvd unknown message:" + msg)
      }

    }
  }
}

説明

loopの引数内でへの呼び出しの前のすべてのコードはreact、アクターがメッセージを待機しようとしているときに呼び出されるように見えます。Idlingここで自分にメッセージを送ります。このメッセージのハンドラーでは、処理を行う前にメールボックスのサイズが 0 であることを確認します。

于 2009-10-13T14:41:23.853 に答える