2015-03-02 73 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

相關問題