Consider the following example. A hello_world actor
sends a "hello" string to mirror actor
, then it terminates immediately. What will happen to the response world
returned from mirror actor
? Ignored? Left in hello_world actor
mailbox? Could the mirror know its response is lost?
behavior mirror(event_based_actor* self)
{
return { [=](std::string s){ return "world"; } };
}
void hello_world(event_based_actor* self, const actor& theMirror)
{
self->send(theMirror, "hello");
}
Consider the following example. A hello_world actor sends a "hello" string to mirror actor, then it terminates immediately. What will happen to the response world returned from mirror actor? Ignored? Left in hello_world actor mailbox?
Assume that hello_world
has already terminated. When the CAF runtime transfers control into mirror
for the next time, the statement return "world"
would attempt to send a reply to the sender. Since the sender no longer exists, the runtime simply discards the message.
Could the
mirror
know its response is lost?
TL;DR: you have to implement your own acknowledgement protocol on top if you need message delivery guarantees.
Long answer: by monitoring an actor, you can hook its termination. Ultimately this just enqueues a specific system message in the monitoring actor's mailbox. Assuming a single-hop scenario where no message-reordering can take place, hello_world
will send a message, terminate, and then the runtime will send a DOWN message to all actors that monitored hello_world
. mirror
's mailbox then contains first the string and then the DOWN message. This means mirror
can only detect a failure after it attempted to send the message.
There is one exception: if you spawn mirror
as a priority-aware actor, it can process messages based on their priority. Think about it as two separate mailboxes per actor. All system messages in CAF have high priority, which means that there exists a scenario where you might be able to detect failure before replying, but only when the runtime transfers control into mirror
after both messages already exist in mirror
's mailbox. If the DOWN message gets delayed and the runtime transfers control into mirror
with just the string message sitting in the mailbox, then you mirror
can't detect failure either.
That said, actors can fail at any time and the runtime can only provide near-real time fault propagation. Therefore, your design must be resilient to such failure, which means you must roll your own acknowledgement mechanism for reliable message delivery.