簡體   English   中英

不同的Akka Actor實例接收消息

[英]Different Akka Actor instances receive messages

教程所述,我在Spray項目中使用Guice創建了依賴項注入。

我的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服務actor,它通過注入其他actor並將消息轉發給這些actor:

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"))

實際上,我看到我有2個CollectionsFinderActor實例-一個實例每1分鍾接收一次調度消息,第二個實例接收HttpServiceActor轉發的消息

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

我做錯了什么?

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

您將不得不注入actor系統,並在每次需要它時查找actor ref。 輕微的改進可能是添加了一個服務,該服務將包裝參與者系統並與參與者進行通信。 然后注入此新服務,而不是參與者等。

那就是框架作者所描述的方式:

我通過在@GenesisActorRef方法中添加@Singleton批注來解決此問題

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM