I know actors are persistent, They are always alive sitting idle as long as there is nothing to do(no messages in the mailbox), So who monitors the mailbox ?
Is it the Actor itself ? but it doesn't have a thread assigned from dispatcher until its having a message.?
Or, is there any background daemon running monitoring mailboxes of each actors?
As #Sarvesh Kumar Singh mentioned, actor is not by default persistent. You can create persistent actor by extending PersistentActor: Akka Persistence.
In fact, when a actor(cell) is created in the actor system hierarchy, its mailbox(Mailbox is a subclass of Runnable) will be attached to the dispatcher, when the actor is started, the dispatcher will then execute the mailbox runnable(defined in the run method) by polling message from the mailbox queue, if there's a message, it will trigger the defined actor receive method to actually handle the message. Message looping(during this run, the messages in the queue will the be handled into batch, if handling this batch of batch doesn't pass the limit of dispatcher throughput configuration) is also done in the run method by a recursive call of processMailBox defined in mailbox. At the end of each round, the mail box will attach itself to the dispatcher thread pool for execution if there's messages the actor mail box is scheduled for execution the the loop continues. If not, the loop is broken, the next run will be scheduled when there's message sent to the actor, at this moment, message will be dispatched via the dispatcher attached with the actor cell when you call actorRef ! message, this will make the dispatcher to schedule the message handling, check this out: Dispatch::sendMessage and Dispatcher::dispatch. As explained in Dispatchers, dispatcher's throughput can be configured to determine the maximum number of messages to be processed per actor before the thread jumps to the next actor.
Related
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
do you have any experience with akka actor memory management/leak. Here I have a module use akka actor to communicate with other modules, but as time goes by one of module went down, because of heap memory size.
Is it necessary to send poison pill to children actor after it finished? Because every request in, I'd like to make another actor, each request. Is it necessary to send poison pill again in children actor, if they have their own children actor also?
ps: I'm using Scala Akka
Thanks
Yes, every Actor you create needs to be stopped explicitly. This is typically done by calling context.stop(self) from within the Actor (if it can determine that it is finished with its task) or having the supervisor stop it using context.stop(child).
To prevent running out of memory you can use bounded message queue aka mailbox on the receiving actor: http://doc.akka.io/docs/akka/snapshot/scala/mailboxes.html.
To pick how you want to manage child actors (restart, kill, etc) use supervisor strategy:
http://doc.akka.io/docs/akka/snapshot/general/supervision.html. Supervisor strategy can be picked at any level/parent.
Is it correct to use Thread.sleep(5000); inside an actor? Does it actualy make an actor sleep for 5 seconds? Is there a simple alternative to make an actor sleep for some seconds?
Anything that blocks a thread is not advised within Akka. If the Actor is configured with a a shared thread pool (default behavior) then using Thread.sleep will withhold a thread from that pool that could be doing work for other Actors.
If one really must block, then an actor may be configured to have its own thread. This can be done by configuring a custom dispatcher for the actor to use, the full details are here.
The recognized alternative to blocking is to schedule a callback to the actor via a timer, for example send a message after 5 seconds..
akkaSystem.scheduler.scheduleOnce(5 seconds, actor, "msgFoo")
The Akka scheduler is documented here: http://doc.akka.io/docs/akka/2.3.6/scala/scheduler.html
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.
Newbie question of Akka - I'm reading over Akka Essentials, could someone please explain the difference between Akka Stop/Poison Pill vs. Kill ? The book offers just a small explaination "Kill is synchronous vs. Poison pill is asynchronous." But in what way? Does the calling actor thread lock during this time? Are the children actors notified during kill, post-stop envoked, etc? Example uses of one concept vs. the other?
Many thanks!
Both stop and PoisonPill will terminate the actor and stop the message queue. They will cause the actor to cease processing messages, send a stop call to all its children, wait for them to terminate, then call its postStop hook. All further messages are sent to the dead letters mailbox.
The difference is in which messages get processed before this sequence starts. In the case of the stop call, the message currently being processed is completed first, with all others discarded. When sending a PoisonPill, this is simply another message in the queue, so the sequence will start when the PoisonPill is received. All messages that are ahead of it in the queue will be processed first.
By contrast, the Kill message causes the actor to throw an ActorKilledException which gets handled using the normal supervisor mechanism. So the behaviour here depends on what you've defined in your supervisor strategy. The default is to stop the actor. But the mailbox persists, so when the actor restarts it will still have the old messages except for the one that caused the failure.
Also see the 'Stopping an Actor', 'Killing an Actor' section in the docs:
http://doc.akka.io/docs/akka/snapshot/scala/actors.html
And more on supervision strategies:
http://doc.akka.io/docs/akka/snapshot/scala/fault-tolerance.html
Use PoisonPill whenever you can. It is put on the mailbox and is consumed like any other message. You can also use "context.stop(self)" from within an actor.
PoisonPill asynchronously stops the actor after it’s done with all messages that were received into mailbox, prior to PoisonPill.
You can use both actor stop and poison pill to stop processing of actors, and kill to terminate the actor in its entirety.
x.stop is a call you make in akka receive method, will only replace actor state with new actor after calling postStop.
x ! PoisonPill is a method that you pass to actor to stop processing when the actor is running(Recommended). will also replace actor state after calling postStop.
x.kill will terminate the actor and will remove the actor in the actor Path and replace the entire actor with a new actor.