首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展抽象远程执行元和模式匹配(ClassLoading?)在Scala中

扩展抽象远程执行元和模式匹配(ClassLoading?)在Scala中
EN

Stack Overflow用户
提问于 2011-12-26 12:56:17
回答 1查看 293关注 0票数 1

我正在实现一些扩展Actor的抽象类,并提供一些额外的功能1。然而,模式匹配似乎不能在接收语句中工作。如果我从客户端向服务器发送了一个案例对象Connect,并且在服务器中有一个模式匹配,则表单如下:

代码语言:javascript
复制
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)
}

则输出为

代码语言:javascript
复制
Starting to receive, e.g. class ConnectionTest$Connect$
Got something weird: Connect of type class ConnectionTest$Connect$
...

传入的消息在模式匹配中不会被识别为Connect对象,即使getClass说它是。更奇怪的是:m具有与Connect相同的hashCode,并使用ObjectOutputStreamwriteObject序列化到完全相同的ByteArray,但不等同于它(使用==)。我最好的猜测是classLoader不知何故运行不正确,但我不知所措。

下面是我想要写的更完整的例子:

代码语言:javascript
复制
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
    }
  }
}

下面是一个使用示例:

代码语言:javascript
复制
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
  }
}

当我运行这个程序时,输出如下所示。MyMaster的操作方法中的模式匹配无法识别从MyWorker远程接收的Connect消息。尽管getClass.toString对它们的计算结果是相同的,但它们在某种程度上是不同的。我该如何解决这个问题呢?

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

代码语言:javascript
复制
case object Computed(x: Data, y: Result) extends Message

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-26 17:04:32

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8633019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档