2016-11-24 4 views
1

this 자습서에 설명 된대로 Guice를 사용하여 스프레이 프로젝트에 종속성 삽입을 생성했습니다.다른 Аkkа 액터 인스턴스가 메시지를 수신합니다

내 Guice 모듈 :

class ActorsModule extends AbstractModule with ScalaModule with GuiceAkkaActorRefProvider { 
override def configure() { 
    bind[Actor].annotatedWith(Names.named(GenesActor.name)).to[GenesActor] 
    bind[Actor].annotatedWith(Names.named(SearchSegmentsActor.name)).to[SearchSegmentsActor] 
    bind[Actor].annotatedWith(Names.named(CollectionsFinderActor.name)).to[CollectionsFinderActor] 
    bind[Actor].annotatedWith(Names.named(HttpServiceActor.name)).to[HttpServiceActor] 
} 

@Provides 
@Named(GenesActor.name) 
def provideGenesActorRef(@Inject() system: ActorSystem): ActorRef = provideActorRef(system, GenesActor.name) 

@Provides 
@Named(SearchSegmentsActor.name) 
def provideSearchSegmentsActorRef(@Inject() system: ActorSystem): ActorRef = provideActorRef(system, SearchSegmentsActor.name) 

@Provides 
@Named(CollectionsFinderActor.name) 
def provideCollectionsFinderActorRef(@Inject() system: ActorSystem): ActorRef = provideActorRef(system, CollectionsFinderActor.name) 

} 

내가 가진 HTTP 주사 다른 배우와 그 배우에 전달 메시지에 의해 얻을 서비스의 배우 :

object HttpServiceActor extends NamedActor { 
    override final val name: String = "HttpServiceActor" 
} 

class HttpServiceActor @Inject()(@Named(SearchSegmentsActor.name) searchSegmentsActor: ActorRef, 
          @Named(CollectionsFinderActor.name) collectionsFinderActor: ActorRef, 
          @Named(GenesActor.name) genesActor: ActorRef) 
           extends Actor with SearchHttpService with ActorLogging { 

       def actorRefFactory = context 

       def receive = runRoute(
         sprayRoute(searchSegmentsActor, collectionsFinderActor, genesActor) ~ 
         staticRoute) 

     } 

내가 하나에 주기적으로 메시지를 보낼 필요 이 주입 된 배우 중 내 주요 방법은 다음과 같습니다.

val injector = Guice.createInjector(
    new ConfigModule(), 
    new AkkaModule(), 
    new DaoModule(), 
    new ActorsModule() 
) 

implicit val system = injector.getInstance(classOf[ActorSystem]) 

val service = system.actorOf(GuiceAkkaExtension(system).props(HttpServiceActor.name)) 
val collectionsActor = system.actorOf(GuiceAkkaExtension(system).props(CollectionsFinderActor.name)) 
system.scheduler.schedule(0 seconds, 1 minutes, collectionsActor, new RefreshCollections()) 

IO(Http) ! Http.Bind(service, system.settings.config.getString("app.interface"), system.settings.config.getInt("app.port")) 

실제로 CollectionsFinderActor 인스턴스가 2 개 있습니다. 하나는 1 분마다 예약 된 메시지를 받고 두 번째는 HttpServiceActor가 전달하는 메시지를받습니다.

물론이 것은 아닙니다. CollectionsFinderActor의 동일한 인스턴스가 둘 다 수신되기를 바랍니다. 메시지.

내가 뭘 잘못하고있어?

답변

0

내가 provideGenesActorRef 방법에 @Singleton 주석을 추가하여 문제를 해결 그들은 당신이해야 쓰기

@Provides 
@Named(GenesActor.name) 
def provideGenesActorRef(@Inject() system: ActorSystem): ActorRef = provideActorRef(system, GenesActor.name) 
2

빠른 추측. 기억한다면, guice는 기본적으로 요청할 때마다 서비스의 새로운 인스턴스를 만듭니다. 적어도 재사용을 약속하지는 않습니다.

액터 시스템을 주입해야하고 필요할 때마다 액터 ref를 조회해야합니다. 경미한 개선은 배우 시스템을 감싸고 배우와의 의사 소통을위한 서비스를 추가하는 것입니다. 그리고 대신 배우 등의 새로운 서비스를 주입

framework의 저자에 의해 기술 된 방법

:

+0

아카가 다시 만들 수 있도록 배우 싱글 톤을 만들지 마십시오. –

+0

Play 문서를 살펴볼 수 있습니다. 그들은 akka guice를 통합하고 게임을하는 방법을 설명했습니다. 아마도 프로젝트에서 재사용 할 수있는 아이디어가있을 것입니다. https://www.playframework.com/documentation/2.5.x/ScalaAkka – michaJlS

+0

@PavelBernshtam 정답을 수정했습니다. – michaJlS

관련 문제