Мне интересно, почему сообщения печатаются точно в том же порядке, что и в коде.
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
Я ожидал, что порядок иногда будет отличаться от («первый второй третий»), но он продолжает печатать один и тот же порядок при каждом запуске.
Мои ожидания неверны?




Состояние документация по порядку доставки сообщений
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 имеет кому ответить.
@ NZ_21 NZ_21 Поведение было бы таким же, если бы вы создали актера deviceZ и в его получателе выполнили вызовы tell. Они по-прежнему будут получены в порядке вызовов.
@ NZ_21 Важно то, что где исходит из сообщения, независимо от того, находится ли оно внутри системы акторов или вне ее.
Да, интересно, как масштаб (система акторов) определяет, откуда исходит сообщение. Я только начал заниматься хакингом, но я не думаю, что из шаблонного кода очень очевидно, как это происходит на самом деле. Сначала это немного сбивало меня с толку, поскольку вторым аргументом для tell() является sender, но, как вы сказали, это просто ссылка, на которую получатель может ответить. Это не "настоящий" отправитель.
@ NZ_21 NZ_21 Думайте об этом как о стандартном Java ExecutorService с однопоточным B. Если вы находитесь в потоке A, все ваши Runnable, переданные в submit, будут выполняться в том порядке, в котором они были отправлены. Если у вас есть другой поток B, вызывающий submit, его задачи потенциально будут чередоваться с задачами A.
Спасибо за разъяснения. Не понимал, что существует такое большое различие между отправкой от актеров и отправкой от актеров refs...