蛋糕模式w / akka:为多个层提供隐式actor系统

时间:2014-01-30 18:07:39

标签: scala akka cake-pattern

我正在烘焙我的第一个蛋糕图案,所以请耐心等待。

我使用了我的单片应用程序,并将其剪切为功能层。剪切看起来很干净但导致两个依赖于隐式ActorSystem的层。

我试图像这样解决这种依赖:

trait LayerA {
  this: ActorSystemProvider =>
  private implicit val implicitActorSystem = actorSystem
  import implicitActorSystem.dispatcher // implicit execution ctx
  ...
}

......和LayerX

类似

我的汇编类看起来像:

class Assembly extends LayerA with LayerB with LayerX with ActorSystemProvider

其中ActorSystemProvider只是实例化actor系统。

这不起作用,因为当解析依赖关系并且实例化val时,ActorSystem不存在,从而导致NPE。这看起来也很丑陋,我确信必须有一个更好/更简单的方法来处理它。

在使用蛋糕模式时,如何处理图层之间的共享隐式依赖关系,例如ActorSystem

由于

2 个答案:

答案 0 :(得分:10)

自我类型不是构建结构化体系结构的必要条件,实际上我只在特征是图层组件的情况下使用自我类型。所以当我需要将一些隐含的东西放入范围时(例如Spray Client的ActorRefFactory)我只是混合了一个特征:

trait ActorSystemProvider {
  implicit def actorSystem: ActorSystem
}

在最低层(所谓的“世界末日”)上,我有以下代码结构:

trait ServiceStack
  extends SomeModule
     with SomeModule2
     with SomeModule3 
     with ActorSystemProvider 

object ServiceLauncher extends App with ServiceStack {
  val actorSystem = ActorSystem("ServiceName")
}

这是一个过于简单的例子(如果你想要一个基于蛋糕模式的真实系统构建的一个很好的例子,那么你一定要看看Precog系统,example其中不同的模块/图层连接),但不是你可以在需要时混合使用隐式ActorSystem。

答案 1 :(得分:5)

如果你可以懒得而不是急切地实例化val,你可以使implicitActorSystem成为一个懒惰的val而不是val。所以它只在第一次访问时执行。我认为这应该解决NPE的问题。 (@ViktorKlang FYI发布的另一个鲜为人知的有趣事实:如果lazy val的初始化抛出异常,它将尝试在下次访问时重新初始化val。)

另一种方法是使每个需要执行上下文的方法接受隐式的executionContext,如:

trait LayerA {
  def getUser(id: Int)(implicit ec: ExecutionContext) = {
    ...
  }
}