Akka: Пытаюсь понять порядок доставки сообщений между Актерами

Мне интересно, почему сообщения печатаются точно в том же порядке, что и в коде.

import akka.actor.AbstractActor
import akka.actor.ActorRef
import akka.actor.ActorSystem
import akka.actor.Props
import akka.event.Logging
import akka.event.LoggingAdapter

data class Request(val name: String)

class Device : AbstractActor() {
    val log = Logging.getLogger(getContext().getSystem(), this);

    override fun createReceive(): Receive {
        return receiveBuilder().matchEquals("print") { x -> log.info("hello i'm a device") }
                .match(Request::class.java) { x -> log.info("A " + x.name) }
                .build()
    }

    companion object {
        fun props(): Props {
            return Props.create { Device() }
        }
    }
}


fun main(args: Array<String>) {
    val system = ActorSystem.create("container")
    val deviceA = system.actorOf(Device.props())
    val deviceC = system.actorOf(Device.props())
    val deviceD = system.actorOf(Device.props())


    val deviceB = system.actorOf(Device.props())

    deviceA.tell(Request("first "), deviceB)
    deviceA.tell(Request("second"), deviceC)
    deviceA.tell(Request("third"), deviceD)



}

Он распечатывает:

/usr/lib/jvm/java-8-oracle/bin/java -Dvisualvm.id=32047598721041 -javaagent:/opt/intellij-idea-community/lib/idea_rt.jar=41737:/opt/intellij-idea-community/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-8-oracle/jre/lib/deploy.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-8-oracle/jre/lib/javaws.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfxswt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-8-oracle/jre/lib/management-agent.jar:/usr/lib/jvm/java-8-oracle/jre/lib/plugin.jar:/usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar:/home/dell/akka-quickstart-java/target/classes:/home/dell/.m2/repository/com/typesafe/akka/akka-actor_2.12/2.5.19/akka-actor_2.12-2.5.19.jar:/home/dell/.m2/repository/org/scala-lang/scala-library/2.12.8/scala-library-2.12.8.jar:/home/dell/.m2/repository/com/typesafe/config/1.3.3/config-1.3.3.jar:/home/dell/.m2/repository/org/scala-lang/modules/scala-java8-compat_2.12/0.8.0/scala-java8-compat_2.12-0.8.0.jar:/home/dell/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.20/kotlin-stdlib-jdk8-1.3.20.jar:/home/dell/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.3.20/kotlin-stdlib-1.3.20.jar:/home/dell/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.20/kotlin-stdlib-common-1.3.20.jar:/home/dell/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/home/dell/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.20/kotlin-stdlib-jdk7-1.3.20.jar StuffKt
[INFO] [01/31/2019 18:43:16.058] [container-akka.actor.default-dispatcher-2] [akka://container/user/$a] A first 
[INFO] [01/31/2019 18:43:16.059] [container-akka.actor.default-dispatcher-2] [akka://container/user/$a] A second
[INFO] [01/31/2019 18:43:16.059] [container-akka.actor.default-dispatcher-2] [akka://container/user/$a] A third



Я ожидал, что порядок иногда будет отличаться от («первый второй третий»), но он продолжает печатать один и тот же порядок при каждом запуске.

Мои ожидания неверны?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Состояние документация по порядку доставки сообщений

The rule more specifically is that for a given pair of actors, messages sent directly from the first to the second will not be received out-of-order. The word directly emphasizes that this guarantee only applies when sending with the tell operator to the final destination, not when employing mediators or other message dissemination features (unless stated otherwise).

Вы отправляете из основного метода (вне системы акторов) в deviceA.

Вы отправляете нет от субъектов deviceB, deviceC или deviceD. Они просто используются как ссылки на отправителя, поэтому deviceA имеет кому ответить.

Спасибо за разъяснения. Не понимал, что существует такое большое различие между отправкой от актеров и отправкой от актеров refs...

nz_21 31.01.2019 19:49

@ NZ_21 NZ_21 Поведение было бы таким же, если бы вы создали актера deviceZ и в его получателе выполнили вызовы tell. Они по-прежнему будут получены в порядке вызовов.

Sotirios Delimanolis 31.01.2019 19:54

@ NZ_21 Важно то, что где исходит из сообщения, независимо от того, находится ли оно внутри системы акторов или вне ее.

Sotirios Delimanolis 31.01.2019 20:02

Да, интересно, как масштаб (система акторов) определяет, откуда исходит сообщение. Я только начал заниматься хакингом, но я не думаю, что из шаблонного кода очень очевидно, как это происходит на самом деле. Сначала это немного сбивало меня с толку, поскольку вторым аргументом для tell() является sender, но, как вы сказали, это просто ссылка, на которую получатель может ответить. Это не "настоящий" отправитель.

nz_21 31.01.2019 20:12

@ NZ_21 NZ_21 Думайте об этом как о стандартном Java ExecutorService с однопоточным B. Если вы находитесь в потоке A, все ваши Runnable, переданные в submit, будут выполняться в том порядке, в котором они были отправлены. Если у вас есть другой поток B, вызывающий submit, его задачи потенциально будут чередоваться с задачами A.

Sotirios Delimanolis 31.01.2019 21:56

Другие вопросы по теме