2014-01-30 1 views
6

나는 현재 첫 번째 케이크 패턴을 굽고 있으므로 나와 함께하시기 바랍니다.케이크 패턴 (w/akka) : 여러 레이어에 암시 적 actorSystem 제공

나는 작동하는 모 놀리 식 앱을 가져다가 기능적 레이어로 잘라 냈습니다. 컷이 깨끗해 보이지만 묵시적인 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 단순히 배우를 인스턴스화

체계.

종속성이 해결되고 값이 인스턴스화되어 NPE가 발생하면 ActorSystem이 존재하지 않으므로이 작업이 수행되지 않습니다. 이것은 또한보기 흉하게 보이고 그것을 다루는 더 좋고/더 쉬운 방법이 있어야합니다.

이 경우 ActorSystem과 같이 케이크 패턴을 사용할 때 레이어간에 공유 된 암시 적 종속성을 어떻게 처리해야합니까?

감사

답변

10

자기 타입이 굳 아키텍처 구축을위한 요구 사항이 아닙니다 : 실행 문맥이 같은 암시의 ExecutionContext을 받아 들일 필요가있다.

trait ActorSystemProvider { 
    implicit def actorSystem: ActorSystem 
} 

그리고 내가 가지고있는 (그래서 "세계의 끝"이라고 함) 가장 낮은 계층에 : 나는 범위에 어떤 암시를 배치해야합니다 그래서 (스프레이 클라이언트에 대한 예 ActorRefFactory에 대해) 나는 단지의 특성을 혼합 다음 코드 구조 :

trait ServiceStack 
    extends SomeModule 
    with SomeModule2 
    with SomeModule3 
    with ActorSystemProvider 

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

그것은 당신이 실제 시스템의 좋은 예는 케이크 패턴의 상단에 구축하려는 경우 당신은 확실히 Precog 시스템, example 다른 모듈에서 살펴 보셔야합니다 (아주 간략 예제/layers 연결), 필요할 때 암시 적 ActorSystem을 혼합 할 수는 없습니다.

+0

@Alexv'ActorSystemProvider'를 어디에서 참조하는지 이해할 수 없습니다.'myInternalCalculator'와 같은 내부 특성에서'actorSystem'을 어떻게 액세스 할 수 있습니까? 이것은 호출 계층 구조의 깊은 곳에서 사용됩니다. – Jas

+0

@Jas'ActorRefProvider' 대신'ActorSystemProvider'를 사용하는 것처럼 보입니다. 그럼'ServiceLauncher'와 비슷한 것으로 초기화 할 수 있습니다. – 4lex1v

5

당신이 게으르게하지 않고 열심히보다 발스을 인스턴스화 할 수 있다면, 당신은 implicitActorSystem 게으른 발 대신 발 할 수 있습니다. 따라서 처음 액세스 할 때만 실행됩니다. 나는 이것이 NPE의 문제를 해결해야한다고 생각한다. @ViktorKlang이 게시 한 또 다른 흥미로운 사실 ​​FYI : 지연된 val의 초기화로 인해 예외가 발생하면 다음 액세스시 val을 다시 초기화하려고 시도합니다.)

또 다른 방법은 각 메소드를 작성하는 것입니다 형질 레이어의 구성 요소 인 경우 실제로 난 단지의 경우 자기 유형을 사용,

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