2011-12-26 7 views
1

Actorを拡張し、いくつかの追加機能[1]を提供するいくつかの抽象クラスを実装しています。しかし、パターンマッチングは受信ステートメント内では機能していないようです。私は、クライアントからサーバにケースオブジェクトConnectを送信し、フォームのサーバーでパターンマッチを持っている場合:抽象的なリモートアクターとパターンマッチング(クラスローディング?)をスカラで拡張する

println("Starting to receive, e.g. " + Connect.getClass.toString) 
receive { 
    case Connect => println("Got a connected message") 
    case m => println("Got something weird: " + m + " of type " + m.getClass.toString) 
} 

次に出力は、着信メッセージが認識されない

Starting to receive, e.g. class ConnectionTest$Connect$ 
Got something weird: Connect of type class ConnectionTest$Connect$ 
... 

ですgetClassがそうだとしても、パターン一致のConnectオブジェクトと同じです。さらに奇妙な点:mConnectと同じhashCodeを持ち、ObjectOutputStreamwriteObjectを使ってまったく同じByteArrayにシリアル化されますが、それと等しくありません(==を使用)。私の最高の推測では、classLoaderは何らかの形で誤って動作していますが、私は迷っています。ここで

は私が書くしようとしているかのより完全な例です:

import scala.actors.{Actor, OutputChannel} 
import scala.actors.Actor._ 
import scala.actors.remote.RemoteActor 
import scala.actors.remote.RemoteActor._ 
import scala.actors.remote.Node 

abstract class ConnectionTest(masterNode: Node, port: Int) { 

    trait Message 
    case object Connect extends Message 

    abstract class Master extends Actor { 
    def act { 
     RemoteActor.classLoader = getClass.getClassLoader 
     alive(port) 
     register('MasterProcess, self) 

     while (true) { 
     println("Starting to receive, e.g. " + Connect.getClass.toString) 
     receive { 
      case Connect => println("Got a connect message") 
      case m => println("Got something weird: " + m + " of type " + m.getClass.toString) 
     } 
     } 
    } 
    } 

    abstract class Worker extends Actor { 
    def act { 
     RemoteActor.classLoader = getClass.getClassLoader 
     val master = select(masterNode, 'MasterProcess) 
     link(master) 
     master ! Connect 
    } 
    } 
} 

ここでは使用例です:私はこのプログラムを実行すると

object MyConnectionApp extends optional.Application { 

    case class MyConTest(hostname: String, port: Int) extends ConnectionTest(Node(hostname, port), port) { 
    case object MyMaster extends Master 
    case object MyWorker extends Worker 
    } 

    def main(master: Boolean) = { 
    if (master) 
     MyConTest("localhost", 2552).MyMaster start 
    else 
     MyConTest("localhost", 2552).MyWorker start 
    } 
} 

、出力が上記のようです。 MyWorkerからリモートで受信されたConnectメッセージは、アクトメソッドMyMasterのパターンマッチで認識されませんでした。 getClass.toStringが同じことを評価しても、どちらも同じではありません。これをどうすれば解決できますか?

[1]詳細:私は、多数のノードにわたってある種の並列計算のためのフレームワークを実装しています。もっと複雑なケースでは、実際にConnectionTestParallelComputation[Data, Result]に置き換えたいと思います。ここで、DataResultはタイプパラメータです。メッセージはまた、理想的には、私はこのデザインパターンとよく果たしているソリューションを希望

case object Computed(x: Data, y: Result) extends Message 

のように、これらのパラメータに依存するクラスが含まれます。

+0

あなたはakkaとそのリモートアクターを試しましたか?我々は非常に良い見て2.0。ケースオブジェクトの代わりにケースクラスを試すことができますか? – fmpwizard

+0

akkaがこの問題を解決するかどうか知っていますか?ケースクラスに 'Connect'を変更した場合、例外が発生します:' java.io.NotSerializableException:scala.actors.MQueue'。 – davidsd

+0

[this](http://groups.google.com/group/akka-user/browse_thread/thread/48a2d6ce25e1aa2d)は、お互いに話しているリモートアクターの実例です。そう、彼らはあなたがやろうとしていることをしています – fmpwizard

答えて

2

私はテストしていませんが、Messageの特性と実装(オブジェクトConnectを含む)をクラスConnectionTestに入れてはいけないと思います。それらをコンパニオンオブジェクトに入れることができます。それらをクラスに入れると、クラスConnectionTestを含む各インスタンスに対して別個のオブジェクトConnectが存在します(直列化のコンテキストでは、そのインスタンスへの参照があります)。

オブジェクトConnect異なるConnectionTestのインスタンスに属し、互いに一致しません。

+0

ありがとうございました。本当に問題は解決しました。しかし、なぜ私はConnectionTestのインスタンスが異なるのか分かりません。ここでルールを説明できますか? – davidsd

+0

'object'の等価性は、デフォルトで参照の等価性です。私は正しい行動であると思います。したがって、包含するクラスのインスタンスが2つある限り、それらのインスタンスは等しくなく、含まれるオブジェクトは等しくない。 –

関連する問題