Akka Slick and ThreadLocal - scala

I'm using slick to store data in database, and there I use the threadLocalSession to store the sessions.
The repositories are used to do the crud, and I have an Akka service layer that access the slick repositories.
I found this link, where Adam Gent asks something near what I'm asking here: Akka and Java libraries that use ThreadLocals
My concern is about how does akka process a message, as I store the database session in a threadLocal, can I have two messages been processed at the same time in the same thread?
Let's say: Two add user messages (A and B) sent to the userservice, and message A is partially processed, and stopped, thread B start to process in the same thread that thread A has started to process, which will have the session stored in it's localSession?

Each actor processes its messages one at a time, in the order it received them*. Therefore, if you send messages A, B to the same actor, then they are never processed concurrently (of course the situation is different if you send each of the messages to different actors).
The problem with the use of ThreadLocals is that in general it is not guaranteed that an actor processes each of its messages on the same thread.
So if you send a message M1 and then a message M2 to actor A, it is guaranteed that M1 is processed before M2. What is not guaranteed that M2 is processed on the same thread as M1.
In general, you should avoid using ThreadLocals, as the whole point of actors is that they are a unit of consistency, and you are safe to modify their internal state via message passing. If you really need more control on the threads which execute the processing of messages, look into the documentation of dispatchers: http://doc.akka.io/docs/akka/2.1.0/java/dispatchers.html
*Except if you change their mailbox implementation, but that's a non-default behavior.

Related

How can (messaging) queue be scalable?

I frequently see queues in software architecture, especially those called "scalable" with prominent representative of Actor from Akka.io multi-actor platform. However, how can queue be scalable, if we have to synchronize placing messages in queue (and therefore operate in single thread vs multi thread) and again synchronize taking out messages from queue (to assure, that message it taken exactly once)? It get's even more complicated, when those messages can change state of (actor) system - in this case even after taking out message from queue, it cannot be load balanced, but still processed in single thread.
Is it correct, that putting messages in queue must be synchronized?
Is it correct, that putting messages out of queue must be synchronized?
If 1 or 2 is correct, then how is queue scalable? Doesn't synchronization to single thread immediately create bottleneck?
How can (actor) system be scalable, if it is statefull?
Does statefull actor/bean mean, that I have to process messages in single thread and in order?
Does statefullness mean, that I have to have single copy of bean/actor per entire system?
If 6 is false, then how do I share this state between instances?
When I am trying to connect my new P2P node to netowrk, I believe I have to have some "server" that will tell me, who are other peers, is that correct? When I am trying to download torrent, I have to connect to tracker - if there is "server" then we do we call it P2P? If this tracker will go down, then I cannot connect to peers, is that correct?
Is synchronization and statefullness destroying scalability?
Is it correct, that putting messages in queue must be synchronized?
Is it correct, that putting messages out of queue must be synchronized?
No.
Assuming we're talking about the synchronized java keyword then that is a reenetrant mutual exclusion lock on the object. Even multiple threads accessing that lock can be fast as long as contention is low. And each object has its own lock so there are many locks, each which only needs to be taken for a short time, i.e. it is fine-grained locking.
But even if it did, queues need not be implemented via mutual exclusion locks. Lock-free and even wait-free queue data structures exist. Which means the mere presence of locks does not automatically imply single-threaded execution.
The rest of your questions should be asked separately because they are not about message queuing.
Of course you are correct in that a single queue is not scalable. The point of the Actor Model is that you can have millions of Actors and therefore distribute the load over millions of queues—if you have so many cores in your cluster. Always remember what Carl Hewitt said:
One Actor is no actor. Actors come in systems.
Each single actor is a fully sequential and single-threaded unit of computation. The whole model is constructed such that it is perfectly suited to describe distribution, though; this means that you create as many actors as you need.

Akka: what is the reason of processing messages one at a time in an Actor?

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.

Send Akka messages with database update

I am trying to implement a method in scala that performs couple of database updates using Slick (in the same DB transaction) and then sends several akka messages. Both sending messages and db updates should be atomic. In JEE world it happens pretty much transparently with JMS and DB(JPA for instance) participating in the same transaction and being coordinated by JTA. How do I achieve it with Akka and Slick. Examples would be very beneficial.
To continue the discussion in comments, As I see the solution to your problem:
Start with the main actor which performs db interaction. E.g. on message Start it updates database using Slick and saves Connection to actor's instance varibale and send messages to child actors. That actors have to send to your Main actor confirmation, for example message ConfirmTratnsaction. In the reaction on that message you perform commit on previously saved Connection and close it(or release it to the pool). Also, Main actor has to supervise that child actors. If that actor fail after sending message(or timeout occurs) you have to rollback transaction via saved Connection

Simple explanation of Akka 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.

Strange/Random behavior mixing Actors and DaemonActors

This may be related to a previous question, but I am not so sure.......
I have an Scala/Actor-based subsystem that uses 3 cooperating actors to do some work. Each of the Actors is actually a DaemonActor. External messages are sent into a primary Actor, and occasionally messages are sent from a secondary Actor to the primary, asking it to do stuff with the data it collected from the external messages.
I wrote a test-driver Scala program that starts up the subsystem in question, and uses a DaemonActor to send messages to the subsystem (that is to the primary Actor).
It turns out that messages sent into the primary Actor were processed by the primary Actor, but messages sent from the secondary subsystem Actor to the Primary Actor were not processed.
I discovered that if I made the Actor in the test-driver program a non-Deamon Actor, and not a DaemonActor, everything worked as expected. This was 100% deterministic in that when the external test-driver used an Actor, the subsystem always behaved. When the external test-driver used a DaemonActor, the subsystem always mis-behaved. No other changes were made to the code when switching between Actors and DaemonActors.
The make things even stranger, when I made an expanded test driver that used 2 Actors to send 2 different types of messages to the subsystem, I had to make one of the test driver's actor a DaemonActor or the subsystem receiving messages mis-behaved.
Seems pretty random :-)
One caveat to note: The test driver actors actually call methods on a subsystem class which "translates" the method call into a message send to the primary subsystem actor. This is for compatibility with Java code.
I tried a number of different ways to tell if messages where being processed. However I did it I needed some info from the program, while it was running, and I devolved to printing stuff out. Thus my reference to the question thread about printing and flushing buffers. The only thing that seemed to affect behaviour was Actor vs. DaemonActor.
I could send out code, but it would be kind of a lot.
Any insight would be appreciated!
One possible problem is that you haven't started the actors?
What exactly is the workflow around the DaemonActor, and are you using Scala 2.7 or 2.8? If you post your code on a gist or pastebin-type system, I'm sure many of us would be happy to look at it. :)
In 2.8, regular actors prevent the runtime from terminating while they active; DaemonActors, as the name implies, do not. If you are simply sending the DaemonActor one or more messages and then the program ends, it may never even get to the point of sending messages to the other Actors.