2016-11-24 30 views
1

我使用Guice在噴霧項目中創建了依賴注入,如this教程中所述。不同的阿克演員實例接收消息

我吉斯模塊:

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實例 - 一個接收每1分鐘的預定消息,第二個接收由HttpServiceActor轉發的消息

當然,這不是我所期望的 - 我希望CollectionsFinderActor的同一個實例將同時接收消息。

我在做什麼錯了?

回答

0

我通過添加@Singleton註解provideGenesActorRef方法解決了這一問題

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

快速猜測。如果我記得,默認情況下,每次你要求時,guice都會創建一個新的服務實例。至少,它不承諾重用它們。

您必須注入演員系統,並在每次需要時查找演員參考。稍作改進可能會增加一項服務,這將包括演員系統和與演員的溝通。然後注入新的服務,而不是演員等

這是由作者framework描述方式:

+0

他們寫,你應該不允許演員單身人士允許Akka重新創建他們 –

+0

您可以查看Play文檔。他們描述瞭如何整合akka guice和玩,也許你會發現一些想法在你的項目中重用https://www.playframework.com/documentation/2.5.x/ScalaAkka – michaJlS

+0

@PavelBernshtam我糾正了我的答案。 – michaJlS