In akka documentation:
The good news is that Akka actors conceptually each have their own light-weight thread, which is completely shielded from the rest of the system.
What is a light-weight thread? Aren't threads considered to be expensive resources?
They key word here is 'conceptually': indeed JVM/OS threads are (relatively) expensive resources, and for this reason Akka is not implemented with a thread per actor - that would be too heavy.
Akka does make sure each actor only processes one message at a time. This means 'inside the actor' your don't have to worry about concurrently and that is what meant by the statement that 'conceptually' you can think of an actor running on a 'lightweight thread' (though internally it's not implemented using a thread per actor).
Related
I have read that:
Akka ensures that each instance of an actor runs in its own lightweight thread and its messages are processed one at a time.
If this is the case that AKKA actors processes its messages sequentially then how AKKA provides concurrency for a single Actor.
Actors are independent agents of computation, each one is executed strictly sequentially but many actors can be executed concurrently. You can view an Actor as a Thread that costs only about 0.1% of what a normal thread costs and that also has an address to which you can send messages—you can of course manage a queue in your own Thread and use that for message passing but you’d have to implement all that yourself.
If Akka—or the Actor Model—stopped here, then it would indeed not be very useful. The trick is that giving stable addresses (ActorRef) to the Actors enables them to communicate even across machine boundaries, over a network, in a cluster. It also allows them to be supervised for principled failure handling—when a normal Thread throws an exception it simply terminates and nothing is done to fix it.
It is this whole package of encapsulation (provided by hiding everything behind ActorRef), message-based communication that is location transparent, and support for failure handling that makes the Actor Model a perfect fit for expressing distributed systems. And today there is a distributed system of many CPU cores within even the smallest devices.
This is more of a best practices question. Though it does affect performance.
How many dispatchers should I have in one application or actor system?
Is it alright to have for example one dispatcher for consumers, one for producers, one for management...? Or should I keep the number of dispatchers to a bare minimum?
EDIT:
What about blocking I/O operations - reading from a socket for example?
Should the actors who do this have a separate dispatcher?
If you are not blocking (managed or unmanaged) threads then one dispatcher is fine.
Otherwise do not do blocking :). If you really need to, do blocking in a separate dispatcher.
I know that it is not recommended to block in the receive method of an actor, but I believe it can be done (as long as it is not done in too many actors at once).
This post suggests blocking in preStart as one way to solve a problem, so presumably blocking in preStart is safe.
However, I tried to block in preRestart (not preStart) and everything seemed to just hang - no more messages were logged as received.
Also, in cases where it is not safe to block, what is a safe alternative?
It's relatively safe to block in receive when:
the number of blocked actors in total is much smaller than the number of total worker threads. By default there are ten worker threads, so 1-2 blocked actors are fine
blocking actor has its own, dedicated dispatcher (thread pool). Other actors are not affected
When it's not safe to block, good alternative is to... not block ;-). If you are working with legacy API that is inherently blocking you can either have a separate thread pool maintained inside some actor (feels wrong) or use approach 2. above - dedicate few threads to a subset of actors that need to block.
Never ever block an actor.
If your actor is part of an actor hierarchy (and it should be), the actor system is not able to stop it.
The actor's life-cycle (supervision, watchig etc.) is done by messaging.
Stopping a parent actor of a blocking child will not work.
Maybe there are ways to couple the blocking condition with the actor's lifecycle.
But this would lead to overload of complications and bad-style.
So, the best way is to do the blocking part outside of that actor.
E.g. you could run the blocking code via an executor service in a separate thread.
The Typesafe whitepaper (v5) states:
"In different scenarios, actors may be an alternative to: a thread; a Java EE session bean; ..."
I don't understand how an actor is an alternative to a session bean, because they work completely differently: an actor is called serially by passing messages to it and it processes the messages one at a time in the order in which they are sent. That means the running of any business logic inside the actor is synchronised. Session beans on the other hand are pooled - there is a number of them and multiple threads can run the same business logic at any time meaning that the logic is run concurrently.
Can anyone clear up my misunderstanding of this statement?
You can pool Actors (children) or behind Akka Routers (also technically children), so that way you can tune "concurrency".
Too much ejb concurrency can often be a cause of various lock contention and performance degradation.
Meanwhile akka is aimed at async processing and nio. This approach benefits most of all when number of threads is near the number of CPU cores.
Note that akka doesn't enforce exactly one processing thread. See e.g. Akka control threadpool threads
I do have Java application with lot of threads and thread pools. Can we use AKKA to replace the threads and thread pools?
It depends on what your threads are doing. Are they doing blocking IO or taking locks and sharing mutable data between themselves? If so akka might not be a great fit as actors generally should avoid blocking for io or locks. On the other hand, if the threads do isolated non-blocking work, and can communicate via message passing, akka is probably a good fit.
Yes, you absolutely can. Be careful about the above poster's response. That isn't entirely accurate. Actors can do blocking I/O. You just use child actors to represent each blocking connection. The newbie mistake would be to treat actors the same way you would treat a thread... in which case, the poster above's answer would be right. But, if you pass off the blocking to a lower actor and use an ad-hoc actor each time, you'll never have to block the main throughput.
But, forgive me. I have gone off track. In short, yes, you can. But keep in mind there will be a learning curve. Actors programming is a different paradigm and it needs to be handled a bit differently.
However, programming concurrency with actors is leagues easier than with threads and locking (literally). Just make your app reactive instead of time-based and many concurrency concerns just stop existing.
Check out the AKKA docs on their site. They are very thorough. Also the books Akka concurrency and effective Akka. Just keep 'em on the desk as a reference.