我正在使用Akka / Play / Scala等构建一个基于代理的大型/多代理模型的股票交易所,我正在努力了解如何配置我的应用程序。下面是一段代码,说明了我面临的问题类型的一个示例:
class Exchange extends Actor {
val orderRoutingLogic = new OrderRoutingLogic()
val router = {
val marketsForSecurities = securities.foreach { security =>
val marketForSecurity = context.actorOf(Props[DoubleAuctionMarket](
new DoubleAuctionMarket(security) with BasicMatchingEngine), security.name
)
orderRoutingLogic.addMarket(security, marketForSecurity)
}
Router(orderRoutingLogic)
}
在上面的代码段中,我将BasicMatchingEngine
注入DoubleAuctionMarket
。但是我编写了许多不同的匹配引擎,我希望能够在应用程序配置文件中配置注入DoubleAuctionMarket
的匹配引擎的类型。
可以使用typesafe Config和HOCON配置文件完成此级别的应用程序配置吗?
答案 0 :(得分:0)
有趣的案例。如果我理解正确,你想在配置中指定的某些Market
类型中配置MatchingEngine
actor混音?
一些澄清:你不能简单地混合动态类型。我的意思是如果你将MatchingEngine
类型移动到配置 - 只有在解析配置时才会在运行时知道它。那时你将无法实例化new DoubleAuctionMarket(security) with ???SomeClassInstance???
。但也许你可以用聚合替换继承。也许MatchingEngine
的实例可以作为参数传递给Market?
现在,如何从配置中获取MatchingEngine
的实例?简而言之 - Typesafe Config没有FQCN属性的解析器,但使用反射自己做并不困难。这种技术在Akka的许多地方使用。首先看here。 provider
属性设置为fqcn字符串,可以在其他配置中更改为其他提供程序(即RemoteActorRefProvider
)。现在看看它是如何处理以获得Provider
实例的。首先,它只是被读作字符串here。然后ProviderClass
用于实例化实际(运行时)提供者here。 DynamicAccess
是一个帮助反身呼叫的实用程序。它不能通过context.system公开访问,但只是拿一块它或自己实例化,我不认为这是一个大问题。
经过一些修改后,您的代码可能会显示:
class Exchange extends Actor {
val orderRoutingLogic = new OrderRoutingLogic()
val matchingEngineClass = context.system.settings.config.getString("stocks.matching-engine")
val matchingEngine = DynamicAccess.createInstance[MatchingEngine](matchingEngineClass)
val router = {
val marketsForSecurities = securities.foreach { security =>
val marketForSecurity = context.actorOf(DoubleAuctionMarket.props(security, matchingEngine))
orderRoutingLogic.addMarket(security, marketForSecurity)
}
Router(orderRoutingLogic)
}
我已将道具移动到DoubleAuctionMarket的伴侣对象,如akka docs的推荐预备案中所述。使用Props(new Actor())
是危险的做法。