I have a very simple question, but I haven't found anything on the Internet (maybe I don't know how to search for it).
If I deploy an actor (actorSystem.actorOf ...) and I send a message to it immediately, if the Actor hasn't been deployed yet will the messages be enqueued in a "special" queue or will the messages be sent to DeadLetters?
Have a look at the bottom of the mailbox documentation. Your guess is correct that messages are stored in a special queue until the mailbox is ready.
In order to make system.actorOf both synchronous and non-blocking while keeping the return type ActorRef (and the semantics that the returned ref is fully functional), special handling takes place for this case. Behind the scenes, a hollow kind of actor reference is constructed, which is sent to the system’s guardian actor who actually creates the actor and its context and puts those inside the reference. Until that has happened, messages sent to the ActorRef will be queued locally, and only upon swapping the real filling in will they be transferred into the real mailbox.
Actor mailboxes
Related
Is it possible in Akka Actors to install some kind of 'hook' that allows you to run a self-defined piece of code every time a new message arrives in an actor? Note, this is not the moment when the actor starts handling the message with receive but the moment when the message arrives in the actor and is put into its mailbox. Also note that I want to change the default behavior, not just the behavior for one individual actor. Ideally I would change this behavior at just one spot throughout my code and it would affect all actors automatically, or by only requiring 1-2 lines of code in each file/actor (such as an import statement).
For example, using this hook it should be possible to log a message every time it arrives or to calculate and print the fibonacci of the size of the mailbox before/after insertion.
If you control the spawning of the actor (or are willing to use this mailbox as the default for actors which don't specifically set a mailbox), you can use a custom mailbox. See the docs for details.
I have some actors that kill themselves when idle or other system constraints require them to. The actors that have ActorRefs to them are watching for their Terminated(ref), but there is a race condition of messages meant for the actors being sent before the termination arrives and I'm trying to figure out a clean way to handle that.
I was considering subscribing to DeadLetter and using that to signal the sender that their ref is stale and that they need to get or spawn a new target ActorRef.
However, in Akka Typed, I cannot find any way to get to dead letters other than using the untyped co-existence path, so I figure I'm likely approaching this wrong.
Is there a better pattern for dealing dead downstream refs and re-directing messages to a new downstream refs, short of requiring some kind of ack hand-shake for every message?
Consider dead letters as a debugging tool rather something to use to implement delivery guarantees with (true for both Akka typed and untyped).
If an actor needs to be certain that a message was delivered the message protocol will need to include an an ack. To do resending the actor will also need to keep a buffer for in-flight/not yet acknowledged messages to be able to resend.
We have some ideas on an abstraction for different levels of reliability for message delivery, we'll see if that fits in Akka 2.6 or happens later though, prototyped in: https://github.com/akka/akka/pull/25099
Is the following statement correct: when an Actor receives a message, after completing the pattern-matched function, the message goes out of scope and the message is garbage collected?
On the JVM objects may be garbage collected when it is no longer strongly reachable, i.e. there is no chain of "normal" references via that it can be reached from some thread running in the JVM.
So this means, the simple answer to your question is: no. You do not never know, when or even if the message will be garbage collected. What you know is that the reference that goes out of scope is deleted. However, this does not even mean that the message is no longer reachable. The object could still be referenced from some other actor.
Typically, however, if a message is send and the sending actor keeps no reference to it, and the receiving actor removes its reference to it, it should be garbage collected quite soon. Messages are typically short-lived objects so most likely the object will not survive even one GC-cycle.
It is said:
Akka ensures that each instance of an actor runs in its own lightweight thread and that messages are processed one at a time.
Can you please explain what is the reason of processing messages one at a time in an Actor?
This way we can guarantee thread safety inside an Actor.
Because an actor will only ever handle one message at any given time, we can guarantee that accessing the actor's local state is safe to access, even though the Actor itself may be switching Threads which it is executing on. Akka guarantees that the state written while handling message M1 are visible to the Actor once it handles M2, even though it may now be running on a different thread (normally guaranteeing this kind of safety comes at a huge cost, Akka handles this for you).
It also originates from the original Actor model description, which is an concurrency abstraction, described as actors who can only one by one handle messages and respond to these by performing one of these actions: send other messages, change it's behaviour or create new actors.
Is the following statement correct, otherwise how can it be improved?
When an Akka actor is sent a message, a job is submitted to the executor.
When there is a free thread, it calls the job which obtains a lock on
the actor (assuming it can, otherwise another job is taken). The
receive method of the actor is then called and once it completes,
the job is discarded and the thread returned to the pool. The cycle is then repeated.
All the complicated stuff related to concurrent threads is
handled by Akka, freeing the programmer to concentrate on
solving business problems.
More accurate would be:
When a message is sent to an actor, it is placed in this actor's queue called mailbox. At the same time there can be hundreds or thousands of actors having pending messages in their mailboxes. Akka, using limited number of worker threads, selects a subset of such actors and calls their receive method with each and every message from mailbox in chronological order.
More than one thread never handles the same actor. Also Akka may decide to interrupt processing of messages from a mailbox and select different actor to remain fair and avoid starvation. Because one thread is needed for each receive invocation, this method should never block, wait or sleep.