2016-11-24 52 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