2015-03-02 117 views
1

我正在尝试使用akka集群(http://doc.akka.io/docs/akka/2.3.9/scala/cluster-usage.html)将单个层中的Akka应用程序重构为多层结构。在应用程序中有一些具有参数化默认构造函数的actor,例如如何将类作为参数传递给Scala中的实例化

class MyActor(someParam: boolean = true) extends Actor { 
    def receive = { /* message handling here... */ } 
} 

我现在试图创建一个通用路由器参与者,该参与者将路由到具有特定节点的节点。群集配置工作基础上,阿卡网站的例子,我可以创造1个角色的路由到另一个角色演员路由器:根据需要

class MyActorProxy extends Actor { 
    val workerRouter = context.actorOf(FromConfig.props(Props(classOf[MyActor]), name = "workerRouter") 
    def receive = { 
    case msg: Any => 
     val currentSender = sender() 
     workerRouter.tell(msg, currentSender) 
    } 
} 

此方法效果。但是,我需要去创建一些具有相同功能的代理类,这很痛苦。我试图让它工作得更好,而有限的scala经验让它变得困难。这里就是我想要做的事:

abstract class RouterProxy[T <: Actor](routerPath: String) extends Actor { 
    val router = context.actorOf(FromConfig.props(Props(classOf[T])),name=routerPath) 
    def receive = { 
    case msg: Any => { 
     val currentSender = sender() 
     router.tell(msg,currentSender) 
    } 
    } 
} 

class MyActorProxy extends RouterProxy[MyActor](routerPath = "myActorRouter") 

有没有通过一些斯卡拉文档,并通过计算器阅读想出这个,但似乎无法得到它的权利 - 这种方法不会让我创建道具为演员。我见过How to instantiate an instance of type represented by type parameter in Scala,我认为类型信息正在丢失(类型擦除)。

我该如何去将路由器代理传递给路由器代理以允许路由器初始化?

这是编译过程中出现了错误,而初始化路由器:

class type required but T found 

编辑

背景使用一个通用的代理路由器

其原因的做法是重构单层和多层体系结构的应用程序。当运行多层时,我想跳过初始化任何“重”演员。由于我有一个前端节点上以下配置:

akka.actor.deployment { 
    /workerRouter { 
    routee.paths = ["/user/myActor"] 
    cluster.use-role = backend 
    } 
} 

akka.cluster.roles = [frontend] 

和后端节点的[backend]角色,然后当我启动前端节点,MyActor不会被初始化。 MyActor是许多作为主管/经理的演员中的一员。他们中的每一个可能会依次初始化其他一些演员(有时候还会使用路由器)。我正在尝试重构应用程序,以便我可以在不同的层中运行轻量级前端节点,以便在需要时资源沉重的后端节点,但是仍然能够在单个节点上运行所有节点。通过这种方法,我可以将重要经理的初始化添加到我的应用程序引导程序中,并添加一个角色,并且它变成一个多功能应用程序,无需重新编码。

编辑2 我能够让应用程序按预期工作,如果类构造函数不接受任何参数。

MyActor extends Actor { /* ... */ } 

然后在我的抽象类:

abstract class RouterProxy[T <: Actor](routerPath: String) extends Actor { 
    val router = context.actorOf(FromConfig.props(Props[T]),name = routerPath) 
} 

Props[MyActor]工作正常,无参数的演员,但Props(classOf[T])失去类型。

回答

1

你实际上并没有定义另一个类的路由器,你可以做到这一切,通过你的配置文件:

val myActorRouter = system.actorOf(Props[MyActor] 
     .withRouter(FromConfig()) 
     ,"workerRouter") 

其中“workerRouter”在您的application.conf文件的定义如下:

akka.actor.deployment { 
    /workerRouter { 
    router = round-robin 
    nr-of-instances = 5 
    } 
} 

您还可以配置它全部通过代码,如果你有一个非常简单的配置:

val myActorRouter = system.actorOf(Props[MyActor].withRouter(
    RoundRobinRouter(nrOfInstances = 5))) 

无论哪种方式,您最终都会以myActorRouter作为演员参考,您可以发送消息给。在背景中,Akka系统创建了一个MyActor角色池,并将消息转发给他们。路由器自行退出响应,因此您不需要像以前那样欺骗发件人:当路由器向发件人发送消息时,它会直接返回给将消息发送到路由器的参与者。

+0

感谢您的反馈@gangstead - 您是对的,我可以采取这种方法,但我希望能够运行一个节点,而不需要初始化MyActor的所有重组件(当使用多层应用程序时) 。 我想这个问题不是关于为什么我构建冗余,而是更多的一个普遍的Scala编程问题:**我如何解决类型擦除和保留子类打字。** – Brett 2015-03-04 12:33:07

+0

另一个更新在参数化actor上添加。 – Brett 2015-03-04 12:39:02

+0

你见过这个吗?http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html – almendar 2015-03-04 13:24:34

相关问题