In this video, we are going to discuss the challenges of concurrent and parallel programming, which is heavily based on multithreading and mutable shared state. We will try to look around and find out whether there are other options available to overcome these challenges.
- [Andriy Redko] Hi, and welcome to the second section of this course. In the previous section, we have had a brief introduction into the REST architecture style, and state of the RESTful web service development on the JVM platform. In this section, we will get acquainted with the Actor Model and Akka framework. Although both of these are not strictly related to RESTful web services and APIs development, this knowledge will help us a lot to understand the Spray framework design and implementation.
In this section, we will briefly take a look at the concurrency and parallelism as the foundation to build high throughput web applications. We are going to see the pros and cons of traditional Mutable Shared data approach versus share nothing design by exploring Actor Model and Akka framework. It is worth to mention that Actor Model is not the only alteration available, with different forms of non-blocking programming models being the best example.
Now we will move onto the first video of this section, where we're going to discuss the traditional ways of concurrent and parallel programming. In this video, we're going to discuss how the hardware evolution affected the software evolution. Threads, Shared Mutable State, and synchronization became well-known concepts for every software developer, particularly on the JVM platform. However, very quickly, we as the industry realized that writing Scalable software systems, which employ concurrency and parallelism in a right way, is really, really hard.
The chase for keeping up with Moore's Law forced processor manufacturers to shift their focus from delivering increased CPO clock rates to multi-core CPU designs. In turn, such a shift in hardware design led to a deep rethinking of the way software should be built. In order to leverage this new additional computing power, more and more applications, especially the web ones, embraced concurrency and parallelism, effectively moving away from single threaded to multi threaded execution flows.
The future looked bright, at least in theory. Leveraging more cores should lead to linear increase in performance and throughput, as more computations could be done in parallel. In reality, though, it turned out that things do not work out well all the time. At least on JVM platform, concurrency and parallelism, based on multi-threading model, introduces overhead, often very significant. In most cases, the culprit is Mutable Shared State, as multiple threads are not working in isolation, but have to communicate and exchange data with each other.
Not to mention, expensive context switches and cached lines invalidation. If data is shared using read-only access patterns, it does not cause any problems. However, when multiple threads are trying to modify the same data structure simultaneously, it becomes a real issue, also known as a race condition. The consequences may vary, ranging from very hard to reproduce bugs, to catastrophic data loss and corruption.
Synchronization is the key player in coordinating the access to Shared Mutable State during race conditions. In the essence, usage of different synchronization primitives, like for example locks, monitors, mutexes, semaphores, ensures that the read and write operations are properly ordered, and one and only one thread is able to modify the Shared State at any time. Surely there is no such thing as a free lunch, and synchronization is not free, either.
It causes another class of collisions known as Lock Contention. Thread starvation and deadlocks, plus overusing synchronization primitives leads to dramatic performance degradation, basically nullifying the benefits of additional computing resources. At this moment, it becomes apparent that it is really a tough task to properly use concurrency and parallelism based on threads and Shared Mutable State.
Using too many threads is going to slow down the application because of large amounts of context switches required. From other side, not enough threads may not considerably boost application performance, and under utilize the available hardware resources. Presence of Mutable Shared State and mandatory use of synchronization to guard it has a lot of pitfalls like lock contention, thread starvation, and deadlocks.
Probably the most important side of concurrency models based on multi-threading is non-determinism. As such, it is very difficult to reproduce the issues, and as a direct result of that, to find and fix the cause of them. In this video, we have looked at how the shift to multi-core processor design changed the way we used to develop software. Certain level of concurrency and parallelism is the integral part of most of the modern applications, particularly web ones.
We also discussed the traditional ways of achieving concurrency by using multiple threads, and how difficult it is to coordinate the access to Mutable Shared State in such an environment. In the next video, we're going to delve into another concurrency and parallelism model based on message passing and Actors, which is known as Actor Model.
Embark on an exciting journey into the universe of web development using the Scala programming language and frameworks—natural choices for back-end developers building highly scalable, reliable, and reactive RESTful web services and APIs. This training is the starting point for mastering the nonblocking and asynchronous programming models that lie in the heart of the Spray framework. It starts with an introduction to the REST architecture. Then switch gears to the Akka toolkit and framework, building a sample book catalog application along the way.
Once you've learned about the REST architectural style and Actor model—the foundations that the Spray framework is built upon—you'll shape out your own RESTful web services by providing simple route definitions. Further on in the course, author Andriy Redko delves into authentication and authorization, secure transport, documentation, testing, and caching support. Finally, you will learn how to develop the Spray client API to call external web services.
- The Actor model and Akka framework
- RESTful architecture principles and constraints
- Building RESTful services
- Core Spray framework modules such as spray-can, spray-routing, spray-json, spray-caching, and spray-client
- Securing RESTful web services and APIs with Spray
- Configuring Spray applications with HTTPS support
- Documenting Spray RESTful web services using Swagger
- Caching basics
- Calling external RESTful services