2016-11-24 8 views
1

thisチュートリアルの説明に従って、私はGuice with Sprayプロジェクトを作成しました。異なるАkkаActorインスタンスはメッセージを受け取ります

マイ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) 

     } 

をし、私は1つに、定期的にメッセージを送信する必要がありますこの注入された俳優の私の主な方法は次のようになります:

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つは1分ごとにスケジュールされたメッセージを受け取り、もう1つはHttpServiceActorによって転送されたメッセージを受け取ります。

もちろんこれは私が期待しているものではありません - CollectionsFinderActorの同じインスタンスメッセージ。

私は間違っていますか?

答えて

0

私はprovideGenesActorRefメソッドに@Singletonアノテーションを追加することによって、問題を修正しましたが、彼らはあなたがすべきことを書く

@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

関連する問題