我正在實現一些擴展Actor並提供一些額外功能的抽象類[1]。但是,模式匹配在接收語句中似乎不起作用。如果我從客戶端的形式的服務器發送的情況下,對象Connect
到服務器,並且具有一個模式匹配:在Scala中擴展抽象遠程Actor和模式匹配(ClassLoading?)
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$
...
無法識別傳入消息作爲模式匹配中的Connect
對象,即使getClass表示它是。更奇怪的是:m
與Connect
具有相同的hashCode,並使用ObjectOutputStream
和writeObject
序列化到完全相同的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]更多詳細信息:我正在爲大量節點上的某種並行計算實現框架。在更復雜的情況下,我實際上想用ParallelComputation[Data, Result]
代替ConnectionTest
,其中Data
和Result
是類型參數。消息還包括依賴於這些參數的課,像
case object Computed(x: Data, y: Result) extends Message
理想情況下,我想,隨着這種設計模式打得很好的解決方案。
你有沒有試過阿卡和他們的遠程演員? 2.0我們看起來非常好。你可以嘗試案例類而不是案例對象嗎? – fmpwizard 2011-12-26 06:22:50
你知道阿卡是否解決了這個問題?如果我將'Connect'更改爲一個case類,則會得到一個異常:'java.io.NotSerializableException:scala.actors.MQueue'。 – davidsd 2011-12-26 06:27:28
[this](http://groups.google.com/group/akka-user/browse_thread/thread/48a2d6ce25e1aa2d)是遠程演員互相交談的一個工作示例,所以是的,他們正在做你正在嘗試做的事情 – fmpwizard 2011-12-26 16:46:11