I am looking at the interesting IoT example in the Getting Started Guide.
One thing I noticed is that the handling of the RequestTrackDevice message in the DeviceManager actor (see https://github.com/akka/akka/blob/v2.6.14/akka-docs/src/test/scala/typed/tutorial_4/DeviceGroup.scala#L18-L85) seems to rely on transitive message ordering (as defined in https://doc.akka.io/docs/akka/current/general/message-delivery-reliability.html).
If we look at the code:
val deviceActor = context.spawn(Device(groupId, deviceId), s"device-$deviceId")
context.watchWith(deviceActor, DeviceTerminated(deviceActor, groupId, deviceId))
deviceIdToActor += deviceId -> deviceActor
replyTo ! DeviceRegistered(deviceActor)
We spawn a new actor, and send its ActorRef to the requesting actor. It is not unlikely that his requesting actor would immediately send a message to this ActorRef.
The message from the requester might arrive too early, as this does not seem to be a well defined ordering according to the documentation:
Actor creation is treated as a message sent from the parent to the child, with the same semantics
as discussed above. Sending a message to an actor in a way which could be reordered with this
initial creation message means that the message might not arrive because the actor does not exist
yet. An example where the message might arrive too early would be to create a remote-deployed
actor R1, send its reference to another remote actor R2 and have R2 send a message to R1. An
example of well-defined ordering is a parent which creates an actor and immediately sends a
message to it.
This in practice works fine on a single JVM actor system, but is my conclusion correct that this relies on the “In-JVM” message rules, and not just the “General” rules?
I have encountered this pattern (create a new actor, and need to send its ActorRef to another actor) in my own code, and am interested to see how this is best handled relying on just the “General” rules, so that the actors can be distributed among JVM’s.