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$
...

Connect即使 getClass 说它是,传入的消息也不会被识别为模式匹配中的对象。更奇怪的是:m具有与 相同的 hashCode ,并使用andConnect序列化为完全相同,但不等于它(使用)。我最好的猜测是类加载器在某种程度上表现不正确,但我不知所措。ByteArrayObjectOutputStreamwriteObject==

这是我正在尝试编写的更完整示例:

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
  }
}

当我运行这个程序时,输出如上。Connect远程接收的消息MyWorker未被 的 act 方法中的模式匹配识别MyMaster。即使getClass.toString对它们进行相同的评估,它们在某种程度上也不相同。我怎样才能解决这个问题?

[1] 更多细节:我正在为跨大量节点的某种并行计算实现一个框架。在更复杂的情况下,我实际上想ConnectionTestParallelComputation[Data, Result]whereDataResultare 类型参数替换。消息还将包括依赖于这些参数的类,例如

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

理想情况下,我想要一个与这种设计模式配合得很好的解决方案。

4

1 回答 1

2

我没有测试过,但我认为你不应该把你的Messagetrait 和实现(包括 object Connect)放在 class 中ConnectionTest。您可以将它们放在伴随对象中。如果将它们放在一个类中,则Connect包含类的每个实例都有一个不同的对象ConnectionTest(更糟糕的是,在序列化的上下文中,它具有对该实例的引用)。

属于不同 ConnectionTest 实例的对象Connect是不同的,并且彼此不匹配。

于 2011-12-26T09:04:31.573 回答