Martin Andersson
Martin Andersson

Reputation: 19563

When can an initial message be reordered with the initial creation of an actor?

In Akka, message ordering is only guaranteed between a "given pair of actors" (source).

Same page also states "this rule is not transitive" and gives a theoretical example of actor A sending message M1 to actor C, then sends message M2 to actor B who forwards it to actor C. And so, actor C can receive M1 and M2 in any order.

The page also highlights how creating an actor is the same as sending a message to it and thus, how any other foreign actor could end up sending messages to an actor that does not yet exist:

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 of well-defined ordering is a parent which creates an actor and immediately sends a message to it.

So far so good. The problem is that from what I can gather (I am new to Akka!), the most commonly used pattern in Akka code is to have an actor spawn children and then their shared parent initiates the communication between the children, and so, this is not "well-defined ordering". Is a majority of the world's applications built on Akka fundamentally broken, an accident waiting to happen?

Here's a few examples from Akka themselves.

On this page they have a HelloWorldMain which spawns two children HelloWorld and HelloWorldBot. Then, main calls helloWorld.tell() with HelloWorldBot set as the reply-to reference.

Same page repeats this pattern even more clearly further down in a Main class:

ActorRef<ChatRoom.RoomCommand> chatRoom = context.spawn(ChatRoom.create(), "chatRoom");
ActorRef<ChatRoom.SessionEvent> gabbler = context.spawn(Gabbler.create(), "gabbler");
context.watch(gabbler);
chatRoom.tell(new ChatRoom.GetSession("ol’ Gabbler", gabbler));

The first page quoted gives one example where things can go wrong; if "remote-deployed actor R1, send its reference to another remote actor R2 and have R2 send a message to R1". This is the obvious case. But since I kind of don't like writing applications that just maybe won't work as expected, what exactly are the cases that I need to know about? Remoting being just one of them - or, I suspect, probably the only one? And, what pattern can I use to make the initial communication sort of go as planed? For example, should I await an actor-start event before revealing its reference to the next child (if there even is such a "signal" in Akka)?

I understand that no message is guaranteed to be delivered - and from that follows that not even spawning a child is guaranteed to actually start that child lol. But, this is a separate topic. What I am concerned with specifically is the creation of children and that initial communication between them which Akka has clearly stressed should follow a "well-defined" order, yet, seems like in practice no one really do 😂😂😥

Upvotes: 1

Views: 101

Answers (1)

David Ogren
David Ogren

Reputation: 4800

"When the initial message will be reordered compared to the creation?"

Short answer: Never. If you create an actor the ActorRef is valid immediately, can receive messages immediately, and will be in a valid state before it processes messages.

Longer answer: Reordering can happen if you aren't spawning the actor directly. Because, as you note, the ordering guarantee only applies from one given actor to another. Thus if you introduce an intermediary the guarantee no longer applies. One scenario where this might happen is using remote actor creation, which is why it is mentioned in the docs. But remote actor creation isn't really a typical scenario.

META: I am completely rewriting this answer now to be more succinct now that I think I understand the question better. (If you want to see the original rambling answer, feel free to use the versioning features.)

Upvotes: 2

Related Questions