Actor based development - implementation questions - multithreading

it's my first message here and I'm glad to join this community.
It looks like that everything is now going towards multi-thread development. Big fishes say that it won't take longer to reach hundreds of cores.
I've recently read about actor based development and how wonderful message passing is to handle concurrent programming. In addition, I also read that they can be implemented as a means of method call. In this case, a given object is also an actor.
In other words we no longer call methods arbitrarily. They are post in queue for late processing. A queue then ensures that a object's state(var) isn't modified at the same time because messages are all serialized.
I understand that this model is quite straightforward to implement (at least an experimental one) and perhaps that's why is too difficult to find any technical detail.
My question concerns queues. This is a typical case of multiple-producers and one consumer and I suspect they require some sort of synchronization. Is that true? There would be another solution? I heard they can be implemented as lock-free structures.
I'm not really sure about that. Any comment will be greatly appreciated.
Have a nice day pals

Multiple producers and a single consumer is a great scenario for using Actors, and doesn't require any synchronization. In Scala, you generally don't use any mutable state when working with Actors. You just send over a copy of whatever data needs processing.
You can read more about Actors in Scala in "Programming Scala", available online for free.

If I understood correctly, agents received the messages in a MailBox which behaves like a concurrent queue. So you do not have to care about it. If you want to play with mailbox directly, you can have a look at this nice article from the great "The busy Java developer's guide to Scala" series.

Related

Alternative to Akka for handling tasks sequentially

I have a system which may generate certain events in the lifecycle of a transaction. On every even I need to update a row in a DB and also send out a UI event over websocket.
One option I have is to implement the event processing (DB and UI) in actors thus avoiding any locking issues - also I can afford minor delays so handling this sequentially will greatly simplify matters.
What are alternative ways of handling this in Scala as I feel maybe Actors might be overkill in this case?
There are those blogs stating that actors should be used for "concurrency with state" - though I would like to see a more appropriate mechanism in order to eliminate this option.
Ultimately the main unique benefit for using actors is that they are great for encapsulating mutable variables so that you avoid race conditions.
To do what you describe, you could just use classic threads. In your (possibly simplified) description, I don't see the potential for deadlocks. If you want to something a bit more composable, e.g. a sequence of asynchronous tasks, you can use Scala's Futures.
Not at all sure if this is applicable for Scala, but there's a great lib for Groovy and Java with several concurrency models. I've myself used the Dataflow Concurrency with great success and can recommend it as a light-weight yet manageable model.
Dataflow Concurrency offers an alternative concurrency model, which is
inherently safe and robust. It puts an emphasis on the data and their
flow though your processes instead of the actual processes that
manipulate the data. Dataflow algorithms relieve developers from
dealing with live-locks, race-conditions and make dead-locks
deterministic and thus 100% reproducible. If you don’t get dead-locks
in tests you won’t get them in production.
There are other models available in the linked GPars library as well.
I wouldn't suggest making the threading yourself, unless you have no other choices.
Addendum
After posting I got interested in the topic and made a few searches. Seems like Akka has direct support for Dataflow model also. Or at least has had in some version.
Actors avoid locking issues because they use queues to interact. You can use threads with (blocking) queues and get the same level of safety. The only advantage of Actors over Threads is that an Actor does not spend memory for call stack, thus we can have many more actors than threads in the same amount of core memory. The downside of actor model is that a complex algorithm which could be implemented in single thread require several actors and so actor implementation may look obscured.

Actors at a very deep level, what makes them unique?

I'm not strong in multi-threading programming. And I've been working with akka pretty much enough, but nonetheless I still don't understand what makes actors and akka so neat, convenient, safe and so and so forth. I know that they receive messages, an actor can receive only message at a time. But what of it, what makes them thread-safe?
First of all, actors are just a library built on system threads that involves using shared mutable state and they need somehow to deal with it.
So the question is, how do actors work at a very deep level? I'd also appreciate any link about it.
Björn's answer hits the important point: The actor model encapsulates state and any logic that operates on that state in an actor. The only way to change state from the outside is to send the actor a message.
Because only the actor can modify the state, and because it processes messages serially, there's no possibility of concurrent modification. No race conditions.
Ryan Tanner (disclosure: Ryan works at my company) has a great blog post about what makes actors special: http://blog.goconspire.com/post/64274254800/akka-at-conspire-part-2-why-we-like-actors.
You seem to be mixing up the Actor Model with one concrete implementation of it in Akka.
The code inside a single actor is only run on one thread at any given time processing one single message at any given time. If your actors don't share mutable objects between each other and only communicate via immutable messages then the code is free of the kind of races where you inadvertently change the same object/variable from multiple threads concurrently.
How the implementation runs your actors on top of multiple threads should be irrelevant. But you are of course free to look at the Akka source code.

Trying to identify a design pattern

I am currently working with an inherited piece of code that uses a very interesting design pattern.
The code is split into a number of objects. I am not sure if the term object is applicable since it is a C code, but it is the best analogy. Each object has object-specific data, a thread, and a message queue. All objects primarily communicate by placing pre-defined messages onto each-other's queues. The main idea seems to be is that each object's data is only accessed by one thread. After doing some research I discovered that a few industrial automation applications are written this way (namely the ProfiNET stack and some EIP implementations).
Do you know if this pattern has a name or if it is describes somewhere in the literature? The "Pattern-Oriented Software Architecture" book by Schidt, Stal, et al does not mention it.
Thank you very much.
This sounds somewhat related to the Actor model.
It might be me but is any other pattern except producer consumer combined with mutual exclusion used in what you described ?
Check out Communicating Sequential Processes (CSP)
CSP allows the description of systems in terms of component processes
that operate independently, and interact with each other solely
through message-passing communication
It is actually one of the core design concepts that the Go language is based upon for communicating between goroutines (concurrency).

Differences between DFD (Data Flow Diagram) and activity diagram

I need to know this differences in order to undestand how to use them right.
Which are the differences of DFD and Activity diagram?
Actually, it's reasonably logical. You only have to look at the names.
In data flow diagrams, the lines between "boxes" represent data that flows between components of a system. Because these only show the flow of data, they do not give an indication of sequencing.
In activity diagrams, those lines are simply transitions between activities and do not represent data flow at all. They more represent the sequencing of activities and decisions. You can tell from these what order things happen in.
That's a simplistic explanation but should be a good starting point. Further information can be garnered from Wikipedia for DFDs and activity diagrams.
Explicit bias: I'm a DFDs proponent.
#John is correct that Activity diagrams can be used to represent object flow. #pax equally correct they seldom are.
Two big DFD advantages for me:
Link to object model. Data stores on a DFD provide a really nice way to link the data produced / consumed to the object model. Very useful for consistency and ensuring your thinking is joined up.
They de-emphasise control flow. Far too often designs over-constrain sequencing. Activity diagrams do support concurrency - but it requires the user to (a) remember and (b) use it. So the default is over-serialisation. DFDs don't. They lay bare the real sequence dependencies without any extra effort on the part of the user. Consequently they also make it easier to see causal relationships. If processes a and b both require data input D then it's obvious on the diagram. And hence parallel activity is obvious.
Don't get me wrong - I'm not against Activity diags. Where control flow is the primary consideration I'll use an AD over a DFD. But empirically I'd say I find DFDs a more useful tool in ~70-80% of cases.
Of course, YMMV.
Just a humble opinion from someone who has had to explain processes, both computer and manual, to upper management and CIOs. I have found simple is better and pound-for-pound, DFDs get the message across when I am actually "asked" about details. That being said, the better approach is to always practice the story line and answer in simple answers.
One final comment regarding the age of tools and products. Remember that in most cases these are running the business and work pretty darn good. The adage "you break it (or replace it) and you own it" can make you a hero or make you into a clown.
We have a CIO who wants to replace all mainframe application for the simple reason that they are old technology. One must weigh the consequences and understand if the replacement can handle workload. Have you ever wondered why JPMC, Credit Swiss, Walmart, and Bank of America to name a few still run mainframes?
My apologies for taking it in that direction. Just make sure, whatever analysis tool is used, that all aspects of the replacement are documented including workload, I/O, concurrent users, adoption curve, and scalability.
Data Flow represents flow within one module or one independent code. However Sequence Diagram represents sequence of activity in between different modules.
Yes at some points they may pass the same messages.
I basically use Sequence diagram in interface documents which will be shared with other modules/elements, however DFD will be used in Low level design documents which will be used to develop the code within one module or network element.
If we look closer to a dataflow diagram, we can notice that when a node collects data from all its edges, it starts to process them. And to process, it needs an activity token, which represents access to a processor. Usually the process of obtaining that token is omitted, but it has to exist. Typically, the whole node as a token is put in a double-ended queue, where on the other end of that queue free activities (processors or threads) are stored. A thread pool is a perfect example of such a queue, and the nodes ready to work are represented as tasks. As soon as a node meets activity, they both are taken from the queue and actual processing starts. When processing finishes, activity is returned to the queue. This way we can think of activity as a special kind of token.
So both dataflow and activity diagrams are just simplified variants of a general active-data-flow diagram, with either activities or data tokens omitted. But generally, both kinds of tokens can be represented in a diagram simultaneously.
Programmers used to think about threads as activities, but if we look at them closer, we notice that when a thread is ready to execute, it gets in a line to processors, and real execution starts only when a free processor switch to that thread. This is absolute analogy as tasks are executed on a thread pool. So from simplified point of view, a thread is an activity, and from more rigorous point of view a thread is a data token and the only real activity is a physical processor. This shows that activity tokens are not different from data tokens. And indeed, we can omit the route of node chasing an activity and consider a dataflow node as an activity itself, which starts to work immediately when all its edges (inputs) contain data.

When should one use the Actor model?

When should the Actor Model be used?
It certainly doesn't guarantee deadlock-free environment.
Actor A can wait for a message from B while B waits for A.
Also, if an actor has to make sure its message was processed before moving on to its next task, it will have to send a message and wait for a "your message was processed" message instead of the straightforward blocking.
What's the power of the model?
Given some concurrency problem, what would you look for to decide whether to use actors or not?
First I would look to define the problem... is the primary motivation a speedup of a nested for loop or recursion? If so a simple task based approach or parallel loop approach will likely work well for you (rather than actors).
However if you have a more complex system that involves dependencies and coordinating shared state, then an actor approach can help. Specifically through use of actors and message passing semantics you can often avoid using explicit locks to protect shared state by actually making copies of that state (messages) and reacting to them.
You can do this quite easily with the classic synchronization problems like dining philosophers and the sleeping barbers problem. But you can also use the 'actor' to help with more modern patterns, i.e. your facade could be an actor, your model view and controller could also be actors that communicate with each other.
Another thing that I've observed is that actor semantics are learnable by most developers and 'safer' than their locked counterparts. This is because they raise the abstraction level and allow you to focus on coordinating access to that data rather than protecting all accesses to the data with locks. As an example, imagine that you have a simple class with a data member. If you choose to place a lock in that class to protect access to that data member then any methods on that class will need to ensure that they are accessing that data member under the lock. This becomes particularly problematic when others (or you) modify the class at a later date, they have to remember to use that lock.
On the other hand if that class becomes an actor and the data member becomes a buffer or port you communicate with via messages, you don't have to remember to take the lock because the semantics are built into the buffer and you will very explicitly know whether you are going to block on that based on the type of the buffer.
-Rick
The usage of Actor is "natural" in at least two cases:
When you can decompose your problem in a set of independent tasks.
When you can decompose your problem in a set of tasks linked by a clear workflow (ie. dataflow programming).
For instance, if you process complex data using a series of filters, it is easy to use a pipeline of actors where each actor receives data from an upstream actor and sets data to a downstream actor.
Of course, this data-flow must not be linear and if a step is slow in your pipeline, instead you can use a pool of actors doing the same job. Another way of solving the load balancing problems would be to use instead a demand-driven approach organized with a kind of virtual Kanban system.
Of course, you will need synchronization between actors in almost all interesting cases, but contrary to the classic multi-thread approach, this synchronization is really "concrete". You can imagine guys in a factory, imagine possible problems (workers run out of the job to do, upstream operations is too fast and intermediate products need a huge storage place, etc.) By analogy, you can then find a solution more easily.
I am not an actor expert but here is my 2 cents when to use actor model:
Actor model is not suited for every concurrent application, for instance if you are creating an application which is multi threaded and works in high concurrency actor model is not made to solve the concurrency issue.
Where actors really comes into play is when you are creating an event driven application. For instance you have an application and you are tracking what are users clicking in your application realtime. You can use actors to do activities realtime segregated by user, device or anything of your business requirement as actors are stateful. So, for example if some users lies in actors which clicked on shirts you can send them notification of some coupon.
Also some applications where actors comes handy are : Finance (Pricing, fraud detection), multiplayer gaming.
Actors are asynchronous and concurrent but does not guarantee message order or time limit as to when the message may be acted upon. Hence atomic transactions cannot be split into Actors.
If the application/task involves no mutable state then Actors are overkill as Actor frameworks go to great lengths to avoid race conditions.

Resources