Search code examples
scalaakkacake-pattern

Cake pattern w/ akka: Providing implicit actorSystem to several layers


I'm currently baking my first cake pattern, so please bear with me.

I took my working monolithic app and I cutted it into functional layers. The cut looks clean but resulted in two of the layers that depend on an implicit ActorSystem.

I tried to solve this dependency like this:

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

... and similarly for LayerX

My assembly class looks like:

class Assembly extends LayerA with LayerB with LayerX with ActorSystemProvider

where ActorSystemProvider simply instantiates the actor system.

This does not work given that the ActorSystem does not exist when the dependencies are resolved and the val's are instantiated, resulting in a NPE. This also looks really ugly and I'm sure there has to be a nicer/easier way to deal with it.

How should I deal with shared implicit dependencies among layers when using the cake pattern, like ActorSystem in this case?

Thanks


Solution

  • Self types is not a requirement for building a caked architecture, actually i use self types only in cases when a trait is a component of a layer. So when i need to place some implicit into the scope (for example ActorRefFactory for Spray Client) i just mix a trait in :

    trait ActorSystemProvider {
      implicit def actorSystem: ActorSystem
    }
    

    And on the lowest layer (so called "end of the world") i have the following code structure:

    trait ServiceStack
      extends SomeModule
         with SomeModule2
         with SomeModule3 
         with ActorSystemProvider 
    
    object ServiceLauncher extends App with ServiceStack {
      val actorSystem = ActorSystem("ServiceName")
    }
    

    It's an oversimplified example (if you want a great example of a real system build on top of a Cake Pattern then you should definitely take a look at the Precog system, example where different modules/layers connects), but not you can mix implicit ActorSystem when you need it.