Наблюдение в системе на основе акки с помощью Spring - PullRequest
0 голосов
/ 11 ноября 2018

Я реализовал пользовательский механизм интеграции Akka с Spring в качестве DI-фреймворка, где я зарегистрировал ActorSystem в качестве компонента с одной областью действия:

@Configuration
internal open class SpringAkkaConfiguration
{
    @Bean
    open fun actorSystem(@Value("\${akka.tcp.port}") akkaTcpPort: Int): ActorSystem
    {
        val config = ConfigFactory
            .defaultApplication()
            .withValue("akka.remote.netty.tcp.port", ConfigValueFactory.fromAnyRef(akkaTcpPort))
            .withValue("akka.remote.netty.tcp.hostname", ConfigValueFactory.fromAnyRef("localhost"))
            .withValue("akka.loglevel", ConfigValueFactory.fromAnyRef("WARNING"))

        return ActorSystem.create("system", config)
    }
}


@Component
internal class SpringActorSystem(private val actorSystem: ActorSystem,
                                 private val beanFactory: BeanFactory) : SpringAkka
{
    override fun announce(actorClass: Class<out Actor>): ActorRef
    {
        val props = Props.create(SpringIndirectActorProducer::class.java, beanFactory, actorClass)
        return actorSystem.actorOf(props, actorClass.simpleName)
    }
}

и в рамках которого я создал два актера «Менеджер», используя пользовательскую аннотацию @Actor, которая указывает на область действия «прототипа»:

@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@Component
@Scope("prototype")
annotation class Actor


@Actor
internal class FirstManager(private val connectionService: ConnectionService) : AbstractActor()
{
    override fun createReceive(): Receive = receiveBuilder().build()
}


@Actor
internal class SecondManager(private val connectionService: ConnectionService) : AbstractActor()
{
    override fun createReceive(): Receive = receiveBuilder().build()
}

Каждый актер забирается из IoC и регистрируется в ActorSystem как ребенок, все прекрасно работало до того момента, как мне пришла идея создания дочерних актеров для менеджеров, чтобы иерархия выглядела следующим образом:

-system
 - FirstManager
    -firstchild
    -secondchild
 -SecondManager
    -first-child
    -second-child

Что было бы хорошим решением для регистрации следующих потомков для каждого менеджера, но не для самой ActorSystem для построения упомянутой иерархии? Каждый ребенок-актер зависит от некоторых других услуг, и я хотел бы иметь возможность вводить их без проблем. Пример:

@Actor
internal class ChildActor(private val anotherService: AnotherService): AbstractActor()
{
    override fun createReceive(): Receive = receiveBuilder().build()
}
...