Scala での簡単な RemoteActor
Scala の Actor 用 API では、リモートプロセスを含むプロセス間通信を実現するための API が用意されているので、今回はこれを試してみる事にする。
RemoteActor の使い方
RemoteActor を実現するには、scala.actors.Actor オブジェクトのメソッドに加え、scala.actors.remote.RemoteActor オブジェクトの各種メソッドを使う事になる。
基本的に、actor や receive メソッドに以下のような RemoteActor 用のメソッドを組み合わせればよい。
- alive メソッドで待ち受けるポート番号を指定
- register メソッドで RemoteActor 対象の Actor にシンボルを付ける
- select メソッドで呼び出す RemoteActor を特定する
とりあえず、簡単な RemoteActor のサンプルを作成してみると以下のようになる。通常の Actor の定義に alive と register メソッドの実行を組み合わせるだけ。
consumerTest.scala(RemoteActor)
import scala.actors.Actor._ import scala.actors.remote.RemoteActor._ object consumerTest extends Application { actor { //ポート番号の設定 alive(9000) //シンボルの設定 register('testActor, self) loop { receive { case msg => { println("received=" + msg) reply("rec-" + msg) } } } } }
次に RemoteActor を呼び出す方を作成すると以下のようになる。select メソッドを使って RemoteActor を取得すれば、通常の Actor と同様に ! や !? メソッドでメッセージを送信する。
producerTest.scala(RemoteActor呼び出し)
import scala.actors.Actor._ import scala.actors.remote.Node import scala.actors.remote.RemoteActor._ object producerTest extends Application { override def main(args: Array[String]) { if (args.length < 1) { println(">scala producerTest [numer]") return } actor { //ノード(ホスト名、ポート番号)とシンボルを指定して //RemoteActor を取得 val consumer = select(Node("localhost", 9000), 'testActor) //実行時引数の1番目をそのまま RemoteActor に送信 consumer !? args(0) match { case msg => println("result=" + msg) } } } }
実行例
まず、RemoteActor を実行しておく。
>scalac consumerTest.scala >scala consumerTest
次に、別プロセスとして呼び出し側を実行する。
>scalac producerTest.scala >scala producerTest test
以下のような結果となり、プロセス間の通信が容易に実現できた。
・・・ >scala consumerTest received=test
・・・ >scala producerTest test result=rec-test