/ / Різні екземпляри Akkа Actor отримують повідомлення - масштаб, akka, guice, спрей

Різні екземпляри Akkа Actor отримують повідомлення - scala, akka, guice, spray

Я створив ін'єкцію залежностей за допомогою проекту Guice in Spray, як описано в це підручник.

Мой модуль 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"))

Насправді я бачу, що у мене є 2 екземпляри CollectionsFinderActor - один отримує заплановані повідомлення кожні 1 хвилину, а другий отримує повідомлення, переслані HttpServiceActor

Звичайно, це не те, що я очікую - я хочу, щоб той самий екземпляр CollectionsFinderActor отримав обидва повідомлення.

Що я роблю неправильно?

Відповіді:

2 для відповіді № 1

Швидке відгадування. Якщо я пам’ятаю, за замовчуванням guice створює новий екземпляр служби кожного разу, коли ви про це просите. Принаймні, це не обіцяє використовувати їх повторно.

Вам доведеться вводити акторну систему та шукатиактор ref кожен раз, коли вам це потрібно. Незначним вдосконаленням може бути додавання послуги, яка охопить систему акторів та спілкування з акторами. Тоді вводьте цю нову послугу замість акторів тощо.

Це спосіб, описаний авторами рамки:


0 для відповіді № 2

Я вирішив проблему, додавши анотацію @Singleton для надання методуGenesActorRef

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