├── .gitignore
├── README.md
├── kuhn_cover.jpg
├── kuhn_cover150.jpg
├── jekyll
├── _config.yml
├── Makefile
├── impressum.md
├── alphabetical.md
├── categories.md
├── _layouts
│ └── page.html
└── videos.md
├── SourceSansPro-Bold.otf
├── SourceSansPro-Bold.ttf
├── SourceSansPro-Light.otf
├── SourceSansPro-Light.ttf
├── SourceSansPro-Italic.otf
├── SourceSansPro-Italic.ttf
├── SourceSansPro-Regular.otf
├── SourceSansPro-Regular.ttf
├── lectures
├── jekyll
│ ├── _config.yml
│ ├── Makefile
│ ├── typed_persistence.md
│ ├── introduction.md
│ ├── typed_testing.md
│ ├── typed_facilities.md
│ ├── distributed2.md
│ ├── scalability.md
│ ├── actors.md
│ ├── typed_protocols.md
│ ├── typed_supervision.md
│ ├── typed_akka.md
│ ├── eventual-consistency.md
│ ├── messages.md
│ ├── failures.md
│ ├── lifecycle.md
│ ├── testing.md
│ ├── design.md
│ ├── persistence.md
│ ├── distributed1.md
│ ├── composition.md
│ ├── responsiveness.md
│ └── _layouts
│ │ └── page.html
├── toc.json
├── typed_persistence.html
├── introduction.html
├── typed_testing.html
├── typed_facilities.html
├── distributed2.html
├── scalability.html
├── actors.html
├── typed_protocols.html
├── typed_supervision.html
├── typed_akka.html
├── eventual-consistency.html
├── messages.html
├── failures.html
├── testing.html
├── lifecycle.html
├── design.html
├── persistence.html
└── responsiveness.html
├── patterns
├── jekyll
│ ├── _config.yml
│ ├── Makefile
│ ├── conflict-detection-and-resolution.md
│ ├── aggregator.md
│ ├── consensus-based.md
│ ├── forward-flow.md
│ ├── event-sourcing.md
│ ├── conflict-free-replicated-data-types.md
│ ├── managed-blocking.md
│ ├── pull.md
│ ├── throttling.md
│ ├── error-kernel.md
│ ├── active–passive.md
│ ├── simple-component.md
│ ├── buh
│ ├── event-stream.md
│ ├── drop.md
│ ├── active–active.md
│ ├── self-contained-message.md
│ ├── complex-command.md
│ ├── sharding.md
│ ├── business-handshake.md
│ ├── circuit-breaker.md
│ ├── resource-pool.md
│ ├── saga.md
│ ├── let-it-crash.md
│ ├── request-response.md
│ ├── resource-encapsulation.md
│ ├── resource-loan.md
│ ├── managed-queue.md
│ ├── domain-object.md
│ ├── ask-pattern.md
│ └── _layouts
│ │ └── page.html
├── conflict-detection-and-resolution.html
├── aggregator.html
├── consensus-based.html
├── forward-flow.html
├── event-sourcing.html
├── conflict-free-replicated-data-types.html
├── managed-blocking.html
├── pull.html
├── throttling.html
├── error-kernel.html
├── active–passive.html
├── simple-component.html
├── event-stream.html
├── drop.html
├── active–active.html
├── self-contained-message.html
├── complex-command.html
├── sharding.html
├── saga.html
├── circuit-breaker.html
├── business-handshake.html
├── resource-pool.html
├── let-it-crash.html
├── request-response.html
├── resource-encapsulation.html
└── resource-loan.html
├── local.css
├── fonts.css
└── impressum.html
/.gitignore:
--------------------------------------------------------------------------------
1 | .*.swp
2 | jekyll/_site
3 | */jekyll/_site
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This holds the source files for the website https://www.reactivedesignpatterns.com/.
2 |
--------------------------------------------------------------------------------
/kuhn_cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/kuhn_cover.jpg
--------------------------------------------------------------------------------
/kuhn_cover150.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/kuhn_cover150.jpg
--------------------------------------------------------------------------------
/jekyll/_config.yml:
--------------------------------------------------------------------------------
1 | # Build settings
2 | markdown: kramdown
3 | permalink: pretty
4 | destination: _site
5 |
--------------------------------------------------------------------------------
/SourceSansPro-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Bold.otf
--------------------------------------------------------------------------------
/SourceSansPro-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Bold.ttf
--------------------------------------------------------------------------------
/SourceSansPro-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Light.otf
--------------------------------------------------------------------------------
/SourceSansPro-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Light.ttf
--------------------------------------------------------------------------------
/SourceSansPro-Italic.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Italic.otf
--------------------------------------------------------------------------------
/SourceSansPro-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Italic.ttf
--------------------------------------------------------------------------------
/SourceSansPro-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Regular.otf
--------------------------------------------------------------------------------
/SourceSansPro-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDesignPatterns/website/HEAD/SourceSansPro-Regular.ttf
--------------------------------------------------------------------------------
/lectures/jekyll/_config.yml:
--------------------------------------------------------------------------------
1 | # Build settings
2 | markdown: kramdown
3 | permalink: pretty
4 | destination: _site
5 |
--------------------------------------------------------------------------------
/patterns/jekyll/_config.yml:
--------------------------------------------------------------------------------
1 | # Build settings
2 | markdown: kramdown
3 | permalink: pretty
4 | destination: _site
5 |
--------------------------------------------------------------------------------
/lectures/jekyll/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: _site
2 |
3 | FILES := $(patsubst %.md,../%.html,$(wildcard *.md))
4 |
5 | all: _site $(FILES)
6 |
7 | _site:
8 | jekyll build
9 |
10 | ../%.html: _site/%/index.html
11 | cp $< $@
12 |
--------------------------------------------------------------------------------
/patterns/jekyll/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: _site
2 |
3 | FILES := $(patsubst %.md,../%.html,$(wildcard *.md))
4 |
5 | all: _site $(FILES)
6 |
7 | _site:
8 | jekyll build
9 |
10 | ../%.html: _site/%/index.html
11 | cp $< $@
12 |
--------------------------------------------------------------------------------
/jekyll/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: _site
2 |
3 | FILES := $(patsubst %.md,../%.html,$(wildcard *.md))
4 |
5 | all: _site $(FILES)
6 |
7 | _site:
8 | jekyll build
9 |
10 | ../index.html: _site/index.html
11 | cp $< $@
12 |
13 | ../%.html: _site/%/index.html
14 | cp $< $@
15 |
--------------------------------------------------------------------------------
/jekyll/impressum.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 |
5 | # Impressum
6 |
7 | **Angaben gemäß §5 TMG:**
8 |
9 | Dr. Roland Kuhn
10 | Am Fasanenhof 16
11 | 34125 Kassel
12 |
13 | **Kontakt:**
14 |
15 | info@reactivedesignpatterns.com
16 |
17 | **Verantwortlich für den Inhalt nach §55 Abs. 2 RStV:**
18 |
19 | Dr. Roland Kuhn
20 |
--------------------------------------------------------------------------------
/lectures/jekyll/typed_persistence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Akka Typed Persistence
4 | video: /videos/Courseware/W08/Akka_Typed_Persistence_V1.mp4
5 | ---
6 |
7 | In this lecture we take a look at the integration of typed actors with Akka
8 | Persistence, implementing the saga pattern as an example. Along the way we
9 | discover how to create a single-use message adapter with ease.
10 |
--------------------------------------------------------------------------------
/lectures/jekyll/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: "Introduction: Why Actors?"
4 | video: /videos/Courseware/W05/Week5-1.mp4
5 | ---
6 |
7 | This first lecture motivates actors as a concurrency abstraction. In particular we discuss
8 |
9 | * threads and locks
10 | * race conditions
11 | * deadlocks
12 |
13 | This leads to the conclusion that we want non-blocking synchronization.
14 |
--------------------------------------------------------------------------------
/lectures/jekyll/typed_testing.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Testing Akka Typed Behaviors
4 | video: /videos/Courseware/W08/Testing_Akka_Typed_Behaviors_V1.mp4
5 | ---
6 |
7 | We have seen in previous weeks that testing actors in their natural habitat
8 | involves asynchronous tests, timeouts, and non-determinism. Since Akka Typed
9 | uses pure behavior functions, we can write deterministic tests without
10 | depending on timing, as demonstrated in this lecture.
11 |
--------------------------------------------------------------------------------
/lectures/jekyll/typed_facilities.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Akka Typed Facilities
4 | video: /videos/Courseware/W08/Akka_Typed_Facilities_V1.mp4
5 | ---
6 |
7 | Working with strictly typed actor references benefits from some new facilities:
8 |
9 | - message adapters
10 | - anonymous child actors for handling foreign protocols
11 | - stashing messages and processing them later
12 | - a receptionist for type-safe service discovery
13 |
14 | These factilities are introduced in this lecture.
15 |
--------------------------------------------------------------------------------
/lectures/jekyll/distributed2.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Actors are Distributed (Part 2)
4 | video: /videos/Courseware/W06/Week6-4b.mp4
5 | ---
6 |
7 | This lecture goes deeper on how the Akka Cluster works. In particular you will see:
8 |
9 | * how the state of each cluster member is managed in an eventually-consistent fashion
10 | * that the feature of lifecycle monitoring demands that the membership list of the cluster must be managed with some consistency
11 |
12 | The effects are demonstrated on the link checker example as well.
13 |
--------------------------------------------------------------------------------
/lectures/jekyll/scalability.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Scalability
4 | video: /videos/Courseware/W07/Week7-2.mp4
5 | ---
6 |
7 | This lecture discusses scalability, starting out from contrasting this characteristic with performance—the goal that is often inadequately placed first. We cover:
8 |
9 | * vertical and horizontal scalability by replicating Actors on a single host or on a cluster
10 | * various routing strategies for distributing requests across the replicas
11 | * how consistent hashing (or “sharding”) allows the replication of stateful Actors.
12 |
--------------------------------------------------------------------------------
/lectures/jekyll/actors.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: The Actor Model
4 | video: /videos/Courseware/W05/Week5-2.mp4
5 | ---
6 |
7 | This lecture gives a more formal introduction to the Actor model. In particular we cover:
8 |
9 | * some historical background
10 | * first steps with the Akka implementation
11 | * handling mutable state within an Actor
12 | * sending and receiving messages
13 | * creating and stopping Actors
14 |
15 | The video concludes with a demonstration of running an Actor System and a summary of what Actors are according to the formal model.
16 |
--------------------------------------------------------------------------------
/lectures/jekyll/typed_protocols.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Introduction to Protocols
4 | video: /videos/Courseware/W08/Introduction_to_protocols_V1.mp4
5 | ---
6 |
7 | This lecture sets the stage for the Akka Typed week: we explore how to express
8 | a communication protocol such that a machine can understand the message
9 | exchange — meaning who shall send which message type and when. In particular we
10 | discuss session types, consisting of a global type that describes the whole
11 | interaction at once, and local projections that specify the expected sequence
12 | of send and receive operations for any single party in isolation.
13 |
--------------------------------------------------------------------------------
/lectures/jekyll/typed_supervision.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Supervision revisited
4 | video: /videos/Courseware/W08/Supervision_revisited_V2.mp4
5 | ---
6 |
7 | This lecture discusses how supervision in Akka Typed differs from the
8 | previously discussed supervision implemented in untyped Akka actors:
9 |
10 | - no more paused actors
11 | - no private state leaks by potentially non-serializable exception objects
12 | - failure-stop model as foreseen by the Actor Model
13 |
14 | The interesting part is that supervision is implemented as a purely functional
15 | behavior decorator, show-casing how libraries can add powerful capabilities to
16 | the Akka Typed system.
17 |
--------------------------------------------------------------------------------
/lectures/jekyll/typed_akka.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Protocols in Akka Typed
4 | video: /videos/Courseware/W08/Protocols_in_Akka_Typed_V1.mp4
5 | ---
6 |
7 | Akka Typed is an evolution of the untyped Akka actor implementation to support
8 | channel types: most importantly, the `ActorRef` now is parameterized with the
9 | type of messages it accepts. This has several other consequences that we
10 | discuss in this lecture.
11 |
12 | The use of more precise types within actor interactions is then demonstrated on
13 | a small example, including how to set up a typed actor system and how to handle
14 | fully typed responses, i.e. continuations of the protocol throughout the full
15 | interchange.
16 |
--------------------------------------------------------------------------------
/lectures/jekyll/eventual-consistency.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Eventual Consistency
4 | video: /videos/Courseware/W06/Week6-5.mp4
5 | ---
6 |
7 | This lecture takes note of the fact that all communication in a distributed system takes time—there is no instantaneous understanding of what a remote component is currently doing. We discuss this starting out from locally implemented strong consistency:
8 |
9 | * by removing the blocking waiting for synchronization we see how consistency is weakened
10 | * we discuss how an Actor is an island of consistency in a sea of inconsistency
11 | * on the example of the Akka Cluster’s member state handling we demonstrate the function and value of CRDTs (conflict-free replicated data types)
12 |
--------------------------------------------------------------------------------
/patterns/jekyll/conflict-detection-and-resolution.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Multiple-master: Conflict detection and resolution
5 |
6 | _“Keep multiple copies of a service running in different locations, accept modifications everywhere, and disseminate all modifications among them.”_
7 |
8 | If you want to change your replication scheme such that it can continue to
9 | operate during a transient network partition, then you will have to make some
10 | compromises. Obviously, it is impossible to reach consensus without
11 | communication, so if all cluster nodes are to make progress in accepting and
12 | processing requests at all times, conflicting actions may be performed.
13 |
14 |
15 | [back to the list](../categories.html)
16 |
--------------------------------------------------------------------------------
/local.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | font-size: 24px;
3 | color: #999;
4 | }
5 | h2 {
6 | font-size: 20px;
7 | color: #999;
8 | }
9 | .footer {
10 | font-size: small;
11 | margin-bottom: 2em;
12 | }
13 | .footer .col-md-6 {
14 | padding: 0px;
15 | }
16 | .navbar {
17 | border-color: #e6e6e6;
18 | border-width: 0px 1px 4px 1px;
19 | }
20 | .video {
21 | border: 2px solid #e6e6e6;
22 | overflow: hidden;
23 | margin: 1.5em 0px;
24 | }
25 | .video p {
26 | border-top: 1px solid #e6e6e6;
27 | padding-top: 5px;
28 | }
29 | p > a > img {
30 | margin: 2em;
31 | }
32 | blockquote {
33 | font-style: italic;
34 | border-left: none;
35 | }
36 | .navbar-toggle {
37 | border: 1px solid #337ab7;
38 | }
39 | .icon-bar {
40 | background: #337ab7;
41 | }
42 |
--------------------------------------------------------------------------------
/lectures/jekyll/messages.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Message Processing Semantics
4 | video: /videos/Courseware/W05/Week5-3.mp4
5 | ---
6 |
7 | In this lecture we take a deeper look at how Actors function. This is fundamentally defined by how they are processing messages. After revisiting their encapsulated nature we cover:
8 |
9 | * in how far Actor behavior runs concurrently
10 | * the execution order of internal logic
11 | * the difference in message ordering guarantees between Akka and Erlang
12 | * in how far message delivery is guaranteed and how to improve on that
13 |
14 | These aspects are demonstrated on the bank account transfer process that was used in the first lecture to demonstrate race conditions and deadlocks. We conclude by enumerating the key effects of focusing on message-passing.
15 |
--------------------------------------------------------------------------------
/patterns/jekyll/aggregator.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Aggregator
5 |
6 | _“Create an ephemeral component if multiple service responses are needed to compute a service call’s result.”_
7 |
8 | We have introduced the [Ask pattern](ask-pattern.html) for the case of requiring a request-response
9 | cycle before a service call can be answered. There are cases, though, where a
10 | larger number of these cycles need to be completed, and none of the requests
11 | depend on the responses of the others—in other words, the request-response
12 | cycles can be made in parallel. Disregarding this opportunity for parallelism
13 | means prolonging the time until the overall response can be sent back to the
14 | client, thus leaving an opportunity for latency reduction unused.
15 |
16 |
17 | [back to the list](../categories.html)
18 |
--------------------------------------------------------------------------------
/patterns/jekyll/consensus-based.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Multiple-master: Consensus-based
5 |
6 | _“Keep multiple copies of a service running in different locations, accept modifications everywhere, and disseminate all modifications among them.”_
7 |
8 | Given a group of people, we have a basic understanding of what consensus means:
9 | within the group, all members agree on a proposal and acknowledge that this
10 | agreement is unanimous. From personal experience, we know that reaching
11 | consensus is a process that can take quite a bit of time and coordination
12 | effort, especially if the matter starts out as being contentious—in other
13 | words, if initially there are multiple competing proposals, and the group must
14 | decide which single one to support.
15 |
16 |
17 | [back to the list](../categories.html)
18 |
--------------------------------------------------------------------------------
/lectures/jekyll/failures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Failure Handling with Actors
4 | video: /videos/Courseware/W06/Week6-1.mp4
5 | ---
6 |
7 | This lecture treats the most important characteristic of Actors, namely how they support handling failures in a principled fashion. Due to their encapsulation, failure is contained within the compartment of the system that is represented by each Actor. We therefore cover:
8 |
9 | * how failure is communicated to a supervisor Actor in order to react to it
10 | * how the supervisor decides its reaction
11 | * helpful utilities offered by Akka for formulating supervision strategies
12 | * how the various reactions (resume/restart/stop) affect the failed Actor
13 | * how a restarted Actor can react to this event
14 |
15 | We summarize these learnings by drawing a diagram of the Actor lifecycle.
16 |
--------------------------------------------------------------------------------
/lectures/jekyll/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Lifecycle Monitoring and The Error Kernel
4 | video: /videos/Courseware/W06/Week6-2.mp4
5 | ---
6 |
7 | In this lecture we build upon what we learned about an Actor’s lifecycle and introduce facilities for monitoring it. We then discuss the consequences of hierarchical supervision for the architecture of our system. In particular we cover:
8 |
9 | * that the only observable lifecycle transition is termination
10 | * that the inability to communicate cannot be distinguished from failure
11 | * how the DeathWatch API in Akka supports using these facts for writing resilient systems
12 | * how failure affects child Actors and consequently that important state needs to be kept near the root of the hierarchy
13 | * how logging works in Akka and how unhandled messages can be observed
14 |
15 |
16 |
--------------------------------------------------------------------------------
/patterns/jekyll/forward-flow.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Forward flow
5 |
6 | _“Let the information and the messages flow directly toward their destination where possible.”_
7 |
8 | This pattern sounds intuitive, maybe even trivial: why would you deliberately
9 | send messages via detours when that is not required? The answer is that this
10 | rarely occurs consciously; it is the result of applying a convenient,
11 | well-known pattern overeagerly. The pattern in question is your good friend the
12 | Request-Response pattern, with or without the Ask pattern’s sugar coating.
13 | Overusing this pattern leads to unnecessary consumption of network bandwidth
14 | and increased response latency; thinking about forward flow lets you recognize
15 | these cases and improve your service quality.
16 |
17 |
18 | [back to the list](../categories.html)
19 |
--------------------------------------------------------------------------------
/lectures/jekyll/testing.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Testing Actor Systems
4 | video: /videos/Courseware/W05/Week5-5.mp4
5 | ---
6 |
7 | This lecture completes the first walkthrough of how to use Actors by introducing the means for testing them. Due to their encapsulation, testing Actors is approached differently from traditional OO testing—mocks cannot be used to deeply introspect their behavior. We will cover:
8 |
9 | * blackbox testing: using messages to stimulate expected responses
10 | * replacing collaborating Actors during tests with Actor stubs
11 | * testing parent–child relationships
12 | * reverse onion testing: Reactive systems are validated in black box tests at increasing granularity, starting from individual Actors and working towards the system roots
13 |
14 | After viewing this lecture you will be well-equipped for the first exercise.
15 |
--------------------------------------------------------------------------------
/lectures/jekyll/design.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Designing Actor Systems
4 | video: /videos/Courseware/W05/Week5-4.mp4
5 | ---
6 |
7 | In this lecture we build an Actor-based link checker application in which multiple actors collaborate. On this example we see how:
8 |
9 | * to split up the overall task into manageable subtasks
10 | * to consider the flow of information through an Actor system
11 | * to incorporate non-Actor tools and libraries that offer blocking or Future-based APIs
12 | * to install and handle timeouts, guarding against runaway processes
13 |
14 | Along this journey we find ourselves considering the interplay between Actor code and other concurrency abstractions, in particular considering where we must be careful so that the Actor encapsulation is not broken. We also see how the use of immutable data structures helps avoid mistakes in this regard.
15 |
--------------------------------------------------------------------------------
/patterns/jekyll/event-sourcing.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Event sourcing
5 |
6 | _“Perform state changes only by applying events. Make them durable by storing the events in a log.”_
7 |
8 | Looking at the [Domain Object pattern](domain-object.html) example, you can see
9 | that all state changes the manager actor performs are coupled to an event that
10 | is sent back to the client that requested this change. Because these events
11 | contain the full history of how the state of the domain object evolved, you may
12 | as well use it for the purpose of making the state changes persistent—this, in
13 | turn, makes the state of the domain object persistent. This pattern was
14 | described in 2005 by Martin Fowler and picked up by Microsoft Research, and
15 | it has shaped the design of the Akka Persistence module.
16 |
17 |
18 | [back to the list](../categories.html)
19 |
--------------------------------------------------------------------------------
/patterns/jekyll/conflict-free-replicated-data-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Multiple-master: Conflict-free replicated data types
5 |
6 | _“Keep multiple copies of a service running in different locations, accept modifications everywhere, and disseminate all modifications among them.”_
7 |
8 | In the [previous pattern](./conflict-detection-and-resolution.html), you
9 | achieved perfect availability of the batch service’s storage component—where
10 | perfect means “it works as long as one replica is reachable”—at the cost of
11 | either losing updates or having to care about manual conflict resolution. You
12 | can improve on this even further, but unfortunately at another cost: it is not
13 | possible to avoid conflicts while maintaining perfect availability without
14 | restricting the data types that can be expressed.
15 |
16 |
17 | [back to the list](../categories.html)
18 |
--------------------------------------------------------------------------------
/lectures/jekyll/persistence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Persistent Actor State
4 | video: /videos/Courseware/W06/Week6-3.mp4
5 | ---
6 |
7 | This lecture treats the storage of persistent state for Actors. It starts out from a comparison between in-place updates and an append-only event log (event-sourcing). In particular we cover:
8 |
9 | * the performance characteristics of these options
10 | * how snapshots can be used to shorten recovery times for event-sourcing
11 | * the tradeoff between throughput and consistency when not waiting for events to be persisted before modifying the Actor state
12 | * how to implement truly reliable delivery
13 | * the impossibility of exactly-once delivery in general, but how to implement effectively exactly-once semantics using idempotent operations
14 |
15 | We conclude this lecture by discussing when and how to perform non-idempotent external effects from your Actors.
16 |
--------------------------------------------------------------------------------
/lectures/jekyll/distributed1.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Actors are Distributed (Part 1)
4 | video: /videos/Courseware/W06/Week6-4a.mp4
5 | ---
6 |
7 | In this lecture we deploy Actors on a cluster of nodes, noticing that this does not change the programming model at all: Actors come fully prepared for remote interaction. This is enabled by hiding all their functionality behind a handle that only allows messages to be sent, the `ActorRef` in Akka. We cover:
8 |
9 | * the impact of remote communication compared to local messaging
10 | * `ActorPath` and its relationship with `ActorRef`
11 | * the definition of what constitutes an Akka Cluster
12 | * how to start up a cluster and run Actors on it
13 | * routing messages to Actors elsewhere on the cluster
14 | * deploying Actors from one node to the other
15 |
16 | Cluster usage is demonstrated on the example of the link checker developed during [an earlier lecture](design.html).
17 |
--------------------------------------------------------------------------------
/lectures/jekyll/composition.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Actor Composition
4 | video: /videos/Courseware/W07/Week7-1.mp4
5 | ---
6 |
7 | This lecture discusses the structurally typed nature of Actors as implemented in untyped Akka. In particular, you learn:
8 |
9 | * that the type of an Actor is defined by the set of messages it accepts
10 | * that the type of the `ActorRef` can fundamentally not express in which state the Actor currently is
11 | * how these liberties allow generic transformations of message streams to be implemented, for example changing message rate or timing
12 | * how the frequently encountered request–response pattern is encoded directly in Akka’s `ask` operator
13 | * that including reply-to addresses allows dynamic composition structures
14 | * how to implement non-blocking result aggregation using Futures
15 | * how to delegate risky operations
16 | * how to adapt Actor protocols by placing a façade between sender and receiver
17 |
--------------------------------------------------------------------------------
/lectures/jekyll/responsiveness.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Responsiveess
4 | video: /videos/Courseware/W07/Week7-3.mp4
5 | ---
6 |
7 | In this final lecture we discuss the means and tradeoffs involved in achieving the responsiveness that is required of our systems. In particular, we cover:
8 |
9 | * exploiting parallelism to reduce response latency, potentially at the cost of more resource usage
10 | * installing circuit breakers between Actors or services in order to protect the client from service outages as well as protecting the service from being overloaded
11 | * bulk-heading different parts of the system by assigning separate resources, for example different thread pools
12 | * the tradeoffs between detecting failures and maintaining very low response latencies
13 |
14 | In summary, we reach the conclusion that message-driven systems can be scaled vertically and horizontally, and that responsiveness requires both resilience and elasticity.
15 |
--------------------------------------------------------------------------------
/patterns/jekyll/managed-blocking.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Managed blocking
5 |
6 | _“Blocking a resource requires consideration and ownership.”_
7 |
8 | In the example code for how the execution component in the batch job service
9 | provisions new worker nodes, you have already encountered the situation that an
10 | API you are using is designed to block its calling thread. In the case of the
11 | AWS API, there are ways around that, but this is not always the case. Many
12 | libraries or frameworks that you may want to or have to use do not offer the
13 | option of event-driven interaction. Java Database Connectivity (JDBC) is a
14 | well-known example that comes to mind. In order to use these APIs in a Reactive
15 | system component, you need to take special care to properly manage the
16 | resources that are implicitly seized, most notably the threads required for
17 | their execution.
18 |
19 |
20 | [back to the list](../categories.html)
21 |
--------------------------------------------------------------------------------
/patterns/jekyll/pull.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Pull
5 |
6 | _“Have the consumer ask the producer for batches of data.”_
7 |
8 | One challenge in Reactive systems is how to balance the relationship between
9 | producers and consumers of messages—be they requests that need processing or
10 | facts on their way to persistent storage. The difficulty lies in the dynamic
11 | nature of the problems that may arise from incorrect implementations: only
12 | under realistic input load can you observe whether a fast producer might
13 | overwhelm a resource-constrained consumer. Often, your load test environments
14 | are based on business forecasts that may be exceeded in real usage.
15 |
16 | The formulation of the Pull pattern presented here is the result of Roland’s
17 | involvement in the Reactive Streams initiative, where the resulting behavior
18 | is also characterized as dynamic push-pull, an aspect that we will discuss
19 | later.
20 |
21 |
22 | [back to the list](../categories.html)
23 |
--------------------------------------------------------------------------------
/fonts.css:
--------------------------------------------------------------------------------
1 | /* For license and copyright of all fonts below see https://www.fontsquirrel.com/license/source-sans-pro */
2 | @font-face {
3 | font-family: 'Source Sans Pro';
4 | font-style: italic;
5 | font-weight: 400;
6 | src: url(SourceSansPro-Italic.otf) format('opentype'), url(SourceSansPro-Italic.ttf) format('truetype');
7 | }
8 | @font-face {
9 | font-family: 'Source Sans Pro';
10 | font-style: normal;
11 | font-weight: 300;
12 | src: url(SourceSansPro-Light.otf) format('opentype'), url(SourceSansPro-Light.ttf) format('truetype');
13 | }
14 | @font-face {
15 | font-family: 'Source Sans Pro';
16 | font-style: normal;
17 | font-weight: 400;
18 | src: url(SourceSansPro-Regular.otf) format('opentype'), url(SourceSansPro-Regular.ttf) format('truetype');
19 | }
20 | @font-face {
21 | font-family: 'Source Sans Pro';
22 | font-style: normal;
23 | font-weight: 700;
24 | src: url(SourceSansPro-Bold.otf) format('opentype'), url(SourceSansPro-Bold.ttf) format('truetype');
25 | }
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/throttling.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Throttling
5 |
6 | _“Throttle your own output rate according to contracts with other services.”_
7 |
8 | We have discussed how each component can mediate, measure, and react to back
9 | pressure in order to avoid uncontrollable overload situations. With these means
10 | at your disposal, it is not just fair but obligatory that you respect the
11 | ingestion limits of other components. In situations where you outpace consumers
12 | of your outputs, you can slow to match their rate, and you can even ensure that
13 | you do not violate a prearranged rate agreement.
14 |
15 | In the [Circuit Breaker pattern](circuit-breaker.html), you saw that a circuit
16 | breaker can be designed such that it rejects requests that would otherwise lead
17 | to a request rate that is too high. With the Pull pattern, you can turn this
18 | around and not generate requests more quickly than they are allowed to be sent.
19 |
20 |
21 | [back to the list](../categories.html)
22 |
--------------------------------------------------------------------------------
/patterns/jekyll/error-kernel.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Error Kernel
5 |
6 | _“In a supervision hierarchy, keep important application state or functionality near the root while delegating risky operations towards the leaves.”_
7 |
8 | This pattern builds on the [Simple Component](./simple-component.html) pattern and is applicable wherever
9 | components with different failure probability and reliability requirements are
10 | combined into a larger system or application—some functions of the system must
11 | never go down, whereas others are necessarily exposed to failure. Applying the
12 | Simple Component pattern will frequently leave you in this position, so it pays
13 | to familiarize yourself well with the Error Kernel pattern.
14 |
15 | This pattern has been established in Erlang programs for decades and was one of
16 | the main inspirations for Jonas Bonér to implement an Actor framework—Akka—on
17 | the JVM. The name Akka was originally conceived as a palindrome of Actor
18 | Kernel, referring to this core design pattern.
19 |
20 |
21 | [back to the list](../categories.html)
22 |
--------------------------------------------------------------------------------
/patterns/jekyll/active–passive.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Active–passive replication
5 |
6 | _“Keep multiple copies of the service running in different locations, but only accept modifications to the state in one location at any given time.”_
7 |
8 | This pattern is also sometimes referred to as failover or master-slave
9 | replication. You have already seen one particular form of failover: the ability
10 | to restart a component means that after a failure, a new instance is created
11 | and takes over functionality, like passing the baton from one runner to the
12 | next. For a stateful service, the new instance accesses the same persistent
13 | storage location as the previously failed one, recovering the state before the
14 | crash and continuing from there. This works only as long as the persistent
15 | storage is intact; if that fails, then restarting is not possible—the service
16 | will forget all of its previous state and start from scratch. Imagine your web
17 | shop forgetting about all registered users—that would be a catastrophe!
18 |
19 |
20 | [back to the list](../categories.html)
21 |
--------------------------------------------------------------------------------
/patterns/jekyll/simple-component.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Simple Component
5 |
6 | _“A component shall do only one thing, but do it in full.”_
7 |
8 | This pattern applies wherever a system performs multiple functions or the
9 | functions it performs are so complex that they need to be broken into different
10 | components. An example is a text editor that includes spell checking: these are
11 | two separate functions (editing can be done without spell checking, and
12 | spelling can also be checked on the finished text and does not require editing
13 | capabilities), but on the other hand, neither of these functions is trivial.
14 |
15 | The Simple Component pattern derives from the single responsibility
16 | principle that was formulated by Tom DeMarco in his 1979 book Structured
17 | Analysis and System Specification (Prentice Hall). In its abstract form, it
18 | demands to “maximize cohesion and minimize coupling.” Applied to
19 | object-oriented software design, it is usually stated as follows: “A class
20 | should have only one reason to change.”
21 |
22 |
23 | [back to the list](../categories.html)
24 |
--------------------------------------------------------------------------------
/patterns/jekyll/buh:
--------------------------------------------------------------------------------
1 | # Active–active replication
2 |
3 | _“Keep multiple copies of a service running in different locations, and perform all modifications at all of them.”_
4 |
5 | With multiple-master replication patterns, you achieved resilience for the
6 | storage subsystem of the example batch job processing facility by replicating
7 | it across different locations (data centers, availability zones, and so on).
8 | You saw that you can achieve strong consistency only when implementing a
9 | failover mechanism; both CRDT-based replication and conflict detection avoid
10 | this at the cost of not guaranteeing full consistency. One property of failover
11 | is that it takes some time: first, you need to detect that there is trouble,
12 | and then, you must establish consensus about how to fix it—for example, by
13 | switching to another replica. Both activities require communication and
14 | therefore cannot be completed instantaneously. Where this is not tolerable, you
15 | need a different strategy, but because there is no magic bullet, you must
16 | expect different restrictions.
17 |
18 |
19 | [back to the list](../categories.html)
20 |
--------------------------------------------------------------------------------
/patterns/jekyll/event-stream.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Event stream
5 |
6 | _“Publish the events emitted by a component so that the rest of the system can derive knowledge from them.”_
7 |
8 | The events that a component stores in its log represent the sum of all the
9 | knowledge it has ever possessed. This is a treasure trove for the rest of the
10 | system to delve into: although the shopping cart system is only interested in
11 | maintaining the current state of customer activity, other concerns are
12 | tangential to it, such as tracking the popularity of various products. This
13 | secondary concern does not need to be updated in a guaranteed fashion in real
14 | time; it does not matter if it lags behind the most current information by a
15 | few seconds (individual humans usually would not be able to notice even a delay
16 | of hours in this information). Therefore, it would be an unnecessary burden to
17 | have the shopping cart component provide this summary information, and it would
18 | also violate the Simple Component pattern by introducing a second
19 | responsibility.
20 |
21 |
22 | [back to the list](../categories.html)
23 |
--------------------------------------------------------------------------------
/patterns/jekyll/drop.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Drop
5 |
6 | _“Dropping requests is preferable to failing uncontrollably.”_
7 |
8 | Imagine a system that is exposed to uncontrollable user input (for example, a
9 | site on the internet). Any deployment will be finite in both its processing
10 | capability and its buffering capacity, and if user input exceeds the former for
11 | long enough, the latter will be used up and something will need to fail. If
12 | this is not foreseen explicitly, then an automatic out-of-memory killer will
13 | make a decision that is likely to be less satisfactory than a planned
14 | load-shedding mechanism—and shedding load means dropping requests.
15 |
16 | This is more of a philosophy than an implementation pattern. Network protocols,
17 | operating systems, programming platforms, and libraries will all drop packets,
18 | messages, or requests when overloaded; they do so in order to protect the
19 | system so that it can recover when load decreases. In the same spirit, authors
20 | of Reactive systems need to be comfortable with the notion of sometimes
21 | deliberately losing messages.
22 |
23 |
24 | [back to the list](../categories.html)
25 |
--------------------------------------------------------------------------------
/patterns/jekyll/active–active.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Active–active replication
5 |
6 | _“Keep multiple copies of a service running in different locations, and perform all modifications at all of them.”_
7 |
8 | With multiple-master replication patterns, you achieved resilience for the
9 | storage subsystem of the example batch job processing facility by replicating
10 | it across different locations (data centers, availability zones, and so on).
11 | You saw that you can achieve strong consistency only when implementing a
12 | failover mechanism; both CRDT-based replication and conflict detection avoid
13 | this at the cost of not guaranteeing full consistency. One property of failover
14 | is that it takes some time: first, you need to detect that there is trouble,
15 | and then, you must establish consensus about how to fix it—for example, by
16 | switching to another replica. Both activities require communication and
17 | therefore cannot be completed instantaneously. Where this is not tolerable, you
18 | need a different strategy, but because there is no magic bullet, you must
19 | expect different restrictions.
20 |
21 |
22 | [back to the list](../categories.html)
23 |
--------------------------------------------------------------------------------
/patterns/jekyll/self-contained-message.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Self-contained message
5 |
6 | _“Each message will contain all information needed to process a request as well as to understand its response.”_
7 |
8 | When sending a request, you need to remember what you want to do with the
9 | response that will eventually come back. In other words, you need to manage the
10 | state of the larger operation that this exchange is a part of while the request
11 | and response travel between components. This state management can be done
12 | entirely by the requester—storing contextual information—or it can be pushed
13 | out of it by having the entire context travel with the request and response
14 | across the network. In practice, this responsibility is usually shared, leaving
15 | part of the state in the requester and having part of it travel with the
16 | message. The point of this pattern is that you should strive to include
17 | sufficient information in the message so the state that is relevant to the
18 | current request is fully represented—removing and relocating relevant
19 | information should be considered a premature optimization until proven
20 | otherwise.
21 |
22 |
23 | [back to the list](../categories.html)
24 |
--------------------------------------------------------------------------------
/patterns/jekyll/complex-command.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Complex command
5 |
6 | _“Send compound instructions to the resource to avoid excessive network usage.”_
7 |
8 |
9 | You have encapsulated the resources your system uses in components that manage,
10 | represent, and directly implement their functionality. This allows you to
11 | confine responsibility not only for code-modularity reasons (chapter 6) but
12 | also for vertical and horizontal scalability (chapters 4 and 5) and principled
13 | failure handling (chapter 7). The price of all these advantages is that you
14 | introduce a boundary between the resource and the rest of the system that can
15 | only be crossed by asynchronous messaging. The Resource Loan pattern may help
16 | to move a resource as close as possible to its users, but this barrier will
17 | remain, leading to increased latency and, usually, decreased communication
18 | bandwidth. The core of the Complex Command pattern lies in sending the behavior
19 | to the resource in order to save time and network bandwidth in case of
20 | loquacious interchanges between resource and users; the user of the resource is
21 | only interested in the comparatively small result.
22 |
23 |
24 | [back to the list](../categories.html)
25 |
--------------------------------------------------------------------------------
/patterns/jekyll/sharding.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Sharding
5 |
6 | _“Scale out the management of a large number of domain objects by grouping them into shards based on unique and stable object properties.”_
7 |
8 | The [Domain Object pattern](domain-object.html) gives you the ability to wrap
9 | the domain’s state in small components that can, in principle, be distributed
10 | easily across a cluster of network nodes in order to provide the resources for
11 | representing even very large domains that cannot be held in memory by a single
12 | machine. The difficulty then becomes how to address the individual domain
13 | objects without having to maintain a directory that lists every object’s
14 | location—such a directory could easily reach a size that is impractical to hold
15 | in memory.
16 |
17 | The Sharding pattern places an upper bound on the size of the directory by
18 | grouping the domain objects into a configurable number of shards—the domain is
19 | fractured algorithmically into pieces of manageable size. The term
20 | algorithmically means the association between objects and shards is determined
21 | by a fixed formula that can be evaluated whenever an object needs to be
22 | located.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/business-handshake.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Business handshake
5 |
6 | _“Include identifying and/or sequencing information in the message, and keep retrying until confirmation is received.”_
7 |
8 | While discussing the [Saga pattern](saga.html), we made the implicit assumption that
9 | communication between the saga and the affected components is reliable. We
10 | pictured a group of people standing in the same office and discussing the
11 | process without external disturbances. This is a useful way to begin, because
12 | it allows you to focus on the essential parts of a conversation; but we know
13 | that life does not always work like that—in particular in distributed systems,
14 | where messages can be lost or delayed due to unforeseeable, inexorable
15 | subsystem failures.
16 |
17 | Fortunately, we can treat the two concerns on separate levels: imagining that
18 | the conversation occurs in a busy, noisy office does not invalidate the basic
19 | structure of the business process we are modeling. All that is needed is to
20 | deliver every message more carefully, transmitting it again if it is
21 | overshadowed by some other event. This second level is what the Business
22 | Handshake pattern is all about.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/circuit-breaker.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Circuit Breaker
5 |
6 | _“Protect services by breaking the connection to their users during prolonged failure conditions.”_
7 |
8 | In previous patterns, we discussed how to segregate a system into a hierarchy
9 | of components and subcomponents for the purpose of isolating responsibilities
10 | and encapsulating failure domains. This pattern describes how to safely connect
11 | different parts of the system so that failures do not spread uncontrollably
12 | across them. Its origin lies in electrical engineering: in order to protect
13 | electrical circuits from each other and introduce decoupled failure domains, a
14 | technique was established of breaking the connection when the transmitted power
15 | exceeds a given threshold.
16 |
17 | Translated to a Reactive application, this means the flow of requests from one
18 | component to the next may be broken up deliberately when the recipient is
19 | overloaded or otherwise failing. Doing so serves two purposes: first, the
20 | recipient gets some breathing room to recover from possible load-induced
21 | failures; and second, the sender decides that requests will fail instead of
22 | wasting time with waiting for negative replies.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/resource-pool.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Resource pool
5 |
6 | _“Hide an elastic pool of resources behind their owner.”_
7 |
8 | So far, we have discussed the modeling and operation of a single resource as
9 | well as its interaction with its clients. The astute reader will have noticed
10 | that something is missing from the full picture: the core principles of
11 | Reactive system design demand replication. Recalling the discussion from
12 | chapter 2, you know that resilience cannot be achieved without distributing the
13 | solution across all failure axes—software, hardware, human—and you know that
14 | elasticity requires the ability to distribute the processing load across a
15 | number of resources that are dynamically adjusted to the incoming demand.
16 |
17 | In chapter 13, you learned about different ways to replicate a component. The
18 | effort put into this mechanism depends greatly on how much the component’s
19 | state needs to be synchronized between replicas. This pattern focuses on the
20 | management and external presentation of the replicas. In keeping with the
21 | reasoning presented in chapters 4 and 5, it relies heavily on asynchronous
22 | message passing and location transparency to achieve scalability.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/saga.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Saga
5 |
6 | _“Divide long-lived, distributed transactions into quick local ones with compensating actions for recovery.”_
7 |
8 | The term saga was coined by Hector Garcia-Molina. His paper describes a scheme
9 | for breaking up long-lived business transactions in order to shorten the time
10 | period during which databases need to hold locks—these locks are needed to
11 | ensure atomicity and consistency of the transaction, the downside of which is
12 | that other transactions touching the same data cannot proceed concurrently.
13 |
14 | In a distributed system, you need to break up transactions involving multiple
15 | participants for other reasons: obtaining a shared lock is an expensive
16 | operation that can even be impossible in the face of certain failures like
17 | network partitions. As we discussed in chapter 8, the key to scalability and
18 | loose coupling is to consider each component an island of delimited
19 | consistency. But how do you model business transactions that require inputs
20 | from multiple components while also effecting modifications to multiple
21 | components? It turns out the research topic of sagas provides an effective,
22 | robust solution for many use cases.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/let-it-crash.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Let-it-crash
5 |
6 | _“Prefer a full component restart to internal failure handling.”_
7 |
8 | In chapter 7 of the book we discuss principled failure handling, noting that the
9 | internal recovery mechanisms of each component are limited because they are not
10 | sufficiently separated from the failing parts—everything within a component can
11 | be affected by a failure. This is especially true for hardware failures that
12 | take down the component as a whole, but it is also true for corrupted state
13 | that is the result of some programming error only observable in rare
14 | circumstances. For this reason, it is necessary to delegate failure handling to
15 | a supervisor instead of attempting to solve it within the component.
16 |
17 | This principle is also called crash-only software: the idea is that transient
18 | but rare failures are often costly to diagnose and fix, making it preferable to
19 | recover a working system by rebooting parts of it. This hierarchical
20 | restart-based failure handling makes it possible to greatly simplify the
21 | failure model and at the same time leads to a more robust system that even has
22 | a chance to survive failures that were entirely unforeseen.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/lectures/toc.json:
--------------------------------------------------------------------------------
1 | {"lectures":[
2 | {"uri":"introduction.html","title":"Introduction: Why Actors?"},
3 | {"uri":"actors.html","title":"The Actor Model"},
4 | {"uri":"messages.html","title":"Message Processing Semantics"},
5 | {"uri":"design.html","title":"Designing Actor Systems"},
6 | {"uri":"testing.html","title":"Testing Actor Systems"},
7 | {"uri":"failures.html","title":"Failure Handling with Actors"},
8 | {"uri":"lifecycle.html","title":"Lifecycle Monitoring and The Error Kernel"},
9 | {"uri":"persistence.html","title":"Persistent Actor State"},
10 | {"uri":"distributed1.html","title":"Actors are Distributed (Part 1)"},
11 | {"uri":"distributed2.html","title":"Actors are Distributed (Part 2)"},
12 | {"uri":"eventual-consistency.html","title":"Eventual Consistency"},
13 | {"uri":"composition.html","title":"Actor Composition"},
14 | {"uri":"scalability.html","title":"Scalability"},
15 | {"uri":"responsiveness.html","title":"Responsiveness"},
16 | {"uri":"typed_protocols.html","title":"Introduction to Protocols"},
17 | {"uri":"typed_akka.html","title":"Protocols in Akka Typed"},
18 | {"uri":"typed_testing.html","title":"Testing Akka Typed Behaviors"},
19 | {"uri":"typed_facilities.html","title":"Akka Typed Facilities"},
20 | {"uri":"typed_persistence.html","title":"Akka Typed Persistence"},
21 | {"uri":"typed_supervision.html","title":"Supervision revisited"}
22 | ]}
23 |
--------------------------------------------------------------------------------
/patterns/jekyll/request-response.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Request–response
5 |
6 | _“Include a return address in the message to receive a response.”_
7 |
8 |
9 | This is the most basic interaction pattern we know; it is the foundational
10 | building block for all natural communication, deeply ingrained in human
11 | training. A parent will say something to their infant child, who will initially
12 | gesture or make some sounds in response; later, the child will articulate words
13 | and sentences. Request-response is the way you learn how to speak, and it
14 | underlies all sophisticated forms of communication that you develop later.
15 | Although the response can be nonverbal (in particular, facial expressions, but
16 | also the deliberate absence thereof), in most cases you require a response
17 | before successfully concluding a conversation. The response can be a piece of
18 | information that you asked for or an acknowledgment of receipt for a command
19 | that was given.
20 |
21 | In all these cases, there is one commonality that you need to make explicit
22 | when translating this basic means of communication into a programming pattern:
23 | the process begins with two participants A and B, where A knows how to address
24 | B; when receiving requests, B will need to learn or deduce how to address A in
25 | order to send back a response.
26 |
27 |
28 | [back to the list](../categories.html)
29 |
--------------------------------------------------------------------------------
/patterns/jekyll/resource-encapsulation.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Resource encapsulation
5 |
6 | _“A resource and its lifecycle are responsibilities that must be owned by one component.”_
7 |
8 | From the [Simple Component](simple-component.html) pattern, you know that every
9 | component does only one thing, but does it in full; in other words, each
10 | component is fully responsible for the functionality it provides to the rest of
11 | the system. If we regard that functionality as a resource that is used by other
12 | components—inside or outside the system—then it is clear that resource,
13 | responsibility, and component exactly coincide. These three terms all denote
14 | the same boundary: in this view, resource encapsulation and the single
15 | responsibility principle are the same. The same reasoning can be applied when
16 | considering other resources, in particular those used to provide a component’s
17 | function. These are not implemented but merely are managed or represented: the
18 | essence of the Resource Encapsulation pattern is that you must identify that
19 | component into whose responsibility each resource falls, and place it there.
20 | The resource becomes part of that component’s responsibility. Sometimes this
21 | will lead you to identify the management of an external resource as a notable
22 | responsibility that needs to be broken out into its own simple component.
23 |
24 |
25 | [back to the list](../categories.html)
26 |
--------------------------------------------------------------------------------
/patterns/jekyll/resource-loan.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Resource loan
5 |
6 | _“Give a client exclusive transient access to a scarce resource without transferring ownership.”_
7 |
8 |
9 | A variant of the [Resource Loan](resource-loan.html) pattern is widely used in
10 | non-Reactive systems, the most prominent example being that of a database
11 | connection pool. Database access is represented by a connection object via
12 | which arbitrary operations can be performed. The creation of connections is
13 | expensive, and their number is limited; therefore, a connection is not owned by
14 | client code but is taken from a pool before performing an operation and put
15 | back afterward. The connection pool is responsible for managing the lifecycle
16 | of its connections, and client code obtains temporary permission to use them.
17 | Failures in this scenario are communicated to the client, but their effect on
18 | the connection in question is handled by the pool—the pool owns and supervises
19 | the connections.
20 |
21 | In a Reactive system, you strive to minimize contention as well as the need for
22 | coordination: hence, the classic database connection pool usually only features
23 | as an internal implementation detail of a component whose data storage is
24 | realized by means of a relational database. But you will frequently encounter
25 | the use of scarce resources in your systems, and the same philosophy that
26 | drives the connection pool abstraction is useful in Reactive system design as
27 | well.
28 |
29 |
30 | [back to the list](../categories.html)
31 |
--------------------------------------------------------------------------------
/patterns/jekyll/managed-queue.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Managed queue
5 |
6 | _“Manage an explicit input queue, and react to its fill level.”_
7 |
8 | One of the conclusions drawn from analyzing the [Pull pattern](pull.html) is that it can be
9 | used to mediate back pressure across multiple processing steps in a chain of
10 | components. Transmitting back pressure means halting the entire pipeline when
11 | the a consumer is momentarily overwhelmed, which may, for example, be caused by
12 | unfair scheduling or other execution artifacts, leading to avoidable
13 | inefficiencies in the system.
14 |
15 | This kind of friction can lead to “stuttering” behavior in a processing engine,
16 | where short bursts of messages alternate with periods of inactivity during
17 | which back-pressure signals travel through the system. These bursts can be
18 | smoothed out by employing buffers that allow the data to keep flowing even
19 | during short back-pressure situations. These buffers are queues that
20 | temporarily hold messages while remembering their ordering. We call them
21 | managed queues because their use extends beyond this direct benefit: queues can
22 | be used to monitor and steer the performance of a messaging system. Buffering
23 | and managed queues are even more important at the boundaries of a system that
24 | employs back pressure: if data or requests are ingested from a source that
25 | cannot be slowed down, you need to mediate between the bounded internal
26 | capacity and the potentially unbounded influx.
27 |
28 |
29 | [back to the list](../categories.html)
30 |
--------------------------------------------------------------------------------
/jekyll/alphabetical.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 |
5 | # Patterns sorted alphabetically
6 |
7 | * [Active–active](./patterns/active–active.html)
8 | * [Active–passive](./patterns/active–passive.html)
9 | * [Aggregator](./patterns/aggregator.html)
10 | * [Ask pattern](./patterns/ask-pattern.html)
11 | * [Business Handshake](./patterns/business-handshake.html)
12 | * [Circuit Breaker](./patterns/circuit-breaker.html)
13 | * [Complex command](./patterns/complex-command.html)
14 | * [Conflict detection and resolution](./patterns/conflict-detection-and-resolution.html)
15 | * [Conflict-free replicated data types](./patterns/conflict-free-replicated-data-types.html)
16 | * [Consensus-based](./patterns/consensus-based.html)
17 | * [Domain object](./patterns/domain-object.html)
18 | * [Drop](./patterns/drop.html)
19 | * [Error Kernel](./patterns/error-kernel.html)
20 | * [Event sourcing](./patterns/event-sourcing.html)
21 | * [Event stream](./patterns/event-stream.html)
22 | * [Forward Flow](./patterns/forward-flow.html)
23 | * [Let-it-crash](./patterns/let-it-crash.html)
24 | * [Managed blocking](./patterns/managed-blocking.html)
25 | * [Managed queue](./patterns/managed-queue.html)
26 | * [Pull](./patterns/pull.html)
27 | * [Request–response](./patterns/request-response.html)
28 | * [Resource encapsulation](./patterns/resource-encapsulation.html)
29 | * [Resource loan](./patterns/resource-loan.html)
30 | * [Resource pool](./patterns/resource-pool.html)
31 | * [Saga](./patterns/saga.html)
32 | * [Self-contained message](./patterns/self-contained-message.html)
33 | * [Sharding](./patterns/sharding.html)
34 | * [Simple Component](./patterns/simple-component.html)
35 | * [Throttling](./patterns/throttling.html)
36 |
37 |
--------------------------------------------------------------------------------
/patterns/jekyll/domain-object.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Domain object
5 |
6 | _“Separate the business domain logic from communication and state management.”_
7 |
8 | In chapter 6, we discuss the principle of divide and conquer; and in section
9 | 12.1, you learned how to apply this in the form of the Simple Component
10 | pattern. The resulting components have a clearly defined responsibility: they
11 | do one thing and do it in full. Often, this involves maintaining state that
12 | persists between invocations of these components. Although it may be intuitive
13 | to identify a component with its state—for example, by saying that a shopping
14 | cart in its entirety is implemented by an actor—this has notable downsides:
15 |
16 | * The business logic becomes entangled with the communication protocols and with execution concerns.
17 | * The only available mode of testing this component is through asynchronous integration tests—the implemented business behavior is accessible only via the externally defined protocols.
18 |
19 | The Domain Object pattern describes how to maintain a clear boundary and
20 | separation between the different concerns of business logic, state management,
21 | and communication. This pattern is intuitively understandable without
22 | additional knowledge, but we highly recommended that you study domain-driven
23 | design, because it provides more in-depth techniques for defining the
24 | ubiquitous language used within each bounded context. Bounded contexts
25 | typically correspond to components in your hierarchical system decomposition,
26 | and the ubiquitous language is the natural language in which domain experts
27 | describe the business function of the component.
28 |
29 |
30 | [back to the list](../categories.html)
31 |
--------------------------------------------------------------------------------
/patterns/jekyll/ask-pattern.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 | # Ask
5 |
6 | _“Delegate the handling of a response to a dedicated ephemeral component.”_
7 |
8 |
9 | This pattern can be arrived at by two trains of thought:
10 |
11 | * In a purely message-driven system such as the Actor model, it frequently occurs that after performing a request-response cycle with another Actor, the current business process needs to continue with further steps. Toward this end, the Actor could keep a map of correlation IDs and associated continuation information (such as the details of the ongoing business transaction started by an earlier received message), or it could spawn an ephemeral child Actor, give its address as the return address for the response, and thereby delegate the continuation of the process. The latter is the approach described in Gul Agha’s thesis:
12 | it is the Actor way of thinking. Because this pattern occurs frequently, it may receive special support from libraries or frameworks.
13 |
14 | * Traditional RPC systems are exclusively based on the premise of request-response calls, pretending the same semantics as a local procedure call. Their synchronous presentation results in distributed systems coupled in undesirable ways, as discussed throughout the first part of this book. In order to decouple caller and callee, the locally returned type is changed from a strict result value to a Future—a container for a result value that may arrive later. The continuation of the caller’s business process then needs to be lifted into the Future as well, using transformation combinators to perform the successive steps. This Future is an ephemeral component whose purpose is the reception of the eventual response and the initiation of follow-up actions, exactly like the child Actor in the previous bullet point.
15 |
16 |
17 | [back to the list](../categories.html)
18 |
--------------------------------------------------------------------------------
/jekyll/categories.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | ---
4 |
5 | # Patterns by category
6 |
7 | ## Fault tolerance and recovery patterns
8 |
9 | * [Simple Component](./patterns/simple-component.html)
10 | * [Error Kernel](./patterns/error-kernel.html)
11 | * [Let-it-crash](./patterns/let-it-crash.html)
12 | * [Circuit Breaker](./patterns/circuit-breaker.html)
13 |
14 | ## Replication patterns
15 |
16 | * [Active–passive](./patterns/active–passive.html)
17 | * Multiple-master
18 | * [Consensus-based](./patterns/consensus-based.html)
19 | * [Conflict detection and resolution](./patterns/conflict-detection-and-resolution.html)
20 | * [Conflict-free replicated data types](./patterns/conflict-free-replicated-data-types.html)
21 | * [Active–active](./patterns/active–active.html)
22 |
23 | ## Resource management patterns
24 |
25 | * [Resource encapsulation](./patterns/resource-encapsulation.html)
26 | * [Resource loan](./patterns/resource-loan.html)
27 | * [Complex command](./patterns/complex-command.html)
28 | * [Resource pool](./patterns/resource-pool.html)
29 | * [Managed blocking](./patterns/managed-blocking.html)
30 |
31 | ## Message flow patterns
32 |
33 | * [Request–response](./patterns/request-response.html)
34 | * [Self-contained message](./patterns/self-contained-message.html)
35 | * [Ask pattern](./patterns/ask-pattern.html)
36 | * [Forward Flow](./patterns/forward-flow.html)
37 | * [Aggregator](./patterns/aggregator.html)
38 | * [Saga](./patterns/saga.html)
39 | * [Business Handshake](./patterns/business-handshake.html)
40 |
41 | ## Flow control patterns
42 |
43 | * [Pull](./patterns/pull.html)
44 | * [Managed queue](./patterns/managed-queue.html)
45 | * [Drop](./patterns/drop.html)
46 | * [Throttling](./patterns/throttling.html)
47 |
48 | ## State management and persistence patterns
49 |
50 | * [Domain object](./patterns/domain-object.html)
51 | * [Sharding](./patterns/sharding.html)
52 | * [Event sourcing](./patterns/event-sourcing.html)
53 | * [Event stream](./patterns/event-stream.html)
54 |
55 |
--------------------------------------------------------------------------------
/jekyll/_layouts/page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Angaben gemäß §5 TMG:
46 | 47 |Dr. Roland Kuhn
48 | Habichtsforstweg 10
49 | 34132 Kassel
Kontakt:
52 | 53 |info@reactivedesignpatterns.com
54 | 55 |Verantwortlich für den Inhalt nach §55 Abs. 2 RStV:
56 | 57 |Dr. Roland Kuhn
58 | 59 |“Keep multiple copies of a service running in different locations, accept modifications everywhere, and disseminate all modifications among them.”
46 | 47 |If you want to change your replication scheme such that it can continue to 48 | operate during a transient network partition, then you will have to make some 49 | compromises. Obviously, it is impossible to reach consensus without 50 | communication, so if all cluster nodes are to make progress in accepting and 51 | processing requests at all times, conflicting actions may be performed.
52 | 53 | 54 | 55 |“Create an ephemeral component if multiple service responses are needed to compute a service call’s result.”
46 | 47 |We have introduced the Ask pattern for the case of requiring a request-response 48 | cycle before a service call can be answered. There are cases, though, where a 49 | larger number of these cycles need to be completed, and none of the requests 50 | depend on the responses of the others—in other words, the request-response 51 | cycles can be made in parallel. Disregarding this opportunity for parallelism 52 | means prolonging the time until the overall response can be sent back to the 53 | client, thus leaving an opportunity for latency reduction unused.
54 | 55 | 56 | 57 |“Keep multiple copies of a service running in different locations, accept modifications everywhere, and disseminate all modifications among them.”
46 | 47 |Given a group of people, we have a basic understanding of what consensus means: 48 | within the group, all members agree on a proposal and acknowledge that this 49 | agreement is unanimous. From personal experience, we know that reaching 50 | consensus is a process that can take quite a bit of time and coordination 51 | effort, especially if the matter starts out as being contentious—in other 52 | words, if initially there are multiple competing proposals, and the group must 53 | decide which single one to support.
54 | 55 | 56 | 57 |“Let the information and the messages flow directly toward their destination where possible.”
46 | 47 |This pattern sounds intuitive, maybe even trivial: why would you deliberately 48 | send messages via detours when that is not required? The answer is that this 49 | rarely occurs consciously; it is the result of applying a convenient, 50 | well-known pattern overeagerly. The pattern in question is your good friend the 51 | Request-Response pattern, with or without the Ask pattern’s sugar coating. 52 | Overusing this pattern leads to unnecessary consumption of network bandwidth 53 | and increased response latency; thinking about forward flow lets you recognize 54 | these cases and improve your service quality.
55 | 56 | 57 | 58 |“Perform state changes only by applying events. Make them durable by storing the events in a log.”
46 | 47 |Looking at the Domain Object pattern example, you can see 48 | that all state changes the manager actor performs are coupled to an event that 49 | is sent back to the client that requested this change. Because these events 50 | contain the full history of how the state of the domain object evolved, you may 51 | as well use it for the purpose of making the state changes persistent—this, in 52 | turn, makes the state of the domain object persistent. This pattern was 53 | described in 2005 by Martin Fowler and picked up by Microsoft Research, and 54 | it has shaped the design of the Akka Persistence module.
55 | 56 | 57 | 58 |“Keep multiple copies of a service running in different locations, accept modifications everywhere, and disseminate all modifications among them.”
46 | 47 |In the previous pattern, you 48 | achieved perfect availability of the batch service’s storage component—where 49 | perfect means “it works as long as one replica is reachable”—at the cost of 50 | either losing updates or having to care about manual conflict resolution. You 51 | can improve on this even further, but unfortunately at another cost: it is not 52 | possible to avoid conflicts while maintaining perfect availability without 53 | restricting the data types that can be expressed.
54 | 55 | 56 | 57 |
19 |
20 | {: style="font-size: small; padding: 8px 120px 8px 6em; background: #eee; position: relative;"}
21 |
22 | ## First week: the Actor Model
23 |
24 | * [Introduction: why actors?](lectures/introduction.html) [14:46]
25 | * [The Actor Model](lectures/actors.html) [13:43]
26 | * [Message Processing Semantics](lectures/messages.html) [27:28]
27 | * [Designing Actor Systems](lectures/design.html) [38:43]
28 | * [Testing Actor Systems](lectures/testing.html) [17:16]
29 |
30 | ## Second week: handling failure and state
31 |
32 | * [Failure Handling with Actors](lectures/failures.html) [22:38]
33 | * [Lifecycle Monitoring and The Error Kernel](lectures/lifecycle.html) [24:07]
34 | * [Persistent Actor State](lectures/persistence.html) [24:49]
35 |
36 | ## Third week: distributed computing
37 |
38 | * [Actors are Distributed (Part 1)](lectures/distributed1.html) [36:30]
39 | * [Actors are Distributed (Part 2)](lectures/distributed2.html) [18:17]
40 | * [Eventual Consistency](lectures/eventual-consistency.html) [15:49]
41 | * [Actor Composition](lectures/composition.html) [20:14]
42 | * [Scalability](lectures/scalability.html) [17:00]
43 | * [Responsiveness](lectures/responsiveness.html) [11:13]
44 |
45 | ## Fourth week: typed actors
46 |
47 | * [Introduction to Protocols](lectures/typed_protocols.html) [11:28]
48 | * [Protocols in Akka Typed](lectures/typed_akka.html) [14:27]
49 | * [Testing Akka Typed Behaviors](lectures/typed_testing.html) [8:29]
50 | * [Akka Typed Facilities](lectures/typed_facilities.html) [16:02]
51 | * [Akka Typed Persistence](lectures/typed_persistence.html) [12:49]
52 | * [Supervision revisited](lectures/typed_supervision.html) [10:02]
53 |
54 |
--------------------------------------------------------------------------------
/patterns/managed-blocking.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | “Blocking a resource requires consideration and ownership.”
46 | 47 |In the example code for how the execution component in the batch job service 48 | provisions new worker nodes, you have already encountered the situation that an 49 | API you are using is designed to block its calling thread. In the case of the 50 | AWS API, there are ways around that, but this is not always the case. Many 51 | libraries or frameworks that you may want to or have to use do not offer the 52 | option of event-driven interaction. Java Database Connectivity (JDBC) is a 53 | well-known example that comes to mind. In order to use these APIs in a Reactive 54 | system component, you need to take special care to properly manage the 55 | resources that are implicitly seized, most notably the threads required for 56 | their execution.
57 | 58 | 59 | 60 |In this lecture we take a look at the integration of typed actors with Akka 51 | Persistence, implementing the saga pattern as an example. Along the way we 52 | discover how to create a single-use message adapter with ease.
53 | 54 | 58 |“Have the consumer ask the producer for batches of data.”
46 | 47 |One challenge in Reactive systems is how to balance the relationship between 48 | producers and consumers of messages—be they requests that need processing or 49 | facts on their way to persistent storage. The difficulty lies in the dynamic 50 | nature of the problems that may arise from incorrect implementations: only 51 | under realistic input load can you observe whether a fast producer might 52 | overwhelm a resource-constrained consumer. Often, your load test environments 53 | are based on business forecasts that may be exceeded in real usage.
54 | 55 |The formulation of the Pull pattern presented here is the result of Roland’s 56 | involvement in the Reactive Streams initiative, where the resulting behavior 57 | is also characterized as dynamic push-pull, an aspect that we will discuss 58 | later.
59 | 60 | 61 | 62 |This first lecture motivates actors as a concurrency abstraction. In particular we discuss
51 | 52 |This leads to the conclusion that we want non-blocking synchronization.
59 | 60 | 64 |“Throttle your own output rate according to contracts with other services.”
46 | 47 |We have discussed how each component can mediate, measure, and react to back 48 | pressure in order to avoid uncontrollable overload situations. With these means 49 | at your disposal, it is not just fair but obligatory that you respect the 50 | ingestion limits of other components. In situations where you outpace consumers 51 | of your outputs, you can slow to match their rate, and you can even ensure that 52 | you do not violate a prearranged rate agreement.
53 | 54 |In the Circuit Breaker pattern, you saw that a circuit 55 | breaker can be designed such that it rejects requests that would otherwise lead 56 | to a request rate that is too high. With the Pull pattern, you can turn this 57 | around and not generate requests more quickly than they are allowed to be sent.
58 | 59 | 60 | 61 |We have seen in previous weeks that testing actors in their natural habitat 51 | involves asynchronous tests, timeouts, and non-determinism. Since Akka Typed 52 | uses pure behavior functions, we can write deterministic tests without 53 | depending on timing, as demonstrated in this lecture.
54 | 55 | 59 |“In a supervision hierarchy, keep important application state or functionality near the root while delegating risky operations towards the leaves.”
46 | 47 |This pattern builds on the Simple Component pattern and is applicable wherever 48 | components with different failure probability and reliability requirements are 49 | combined into a larger system or application—some functions of the system must 50 | never go down, whereas others are necessarily exposed to failure. Applying the 51 | Simple Component pattern will frequently leave you in this position, so it pays 52 | to familiarize yourself well with the Error Kernel pattern.
53 | 54 |This pattern has been established in Erlang programs for decades and was one of 55 | the main inspirations for Jonas Bonér to implement an Actor framework—Akka—on 56 | the JVM. The name Akka was originally conceived as a palindrome of Actor 57 | Kernel, referring to this core design pattern.
58 | 59 | 60 | 61 |“Keep multiple copies of the service running in different locations, but only accept modifications to the state in one location at any given time.”
46 | 47 |This pattern is also sometimes referred to as failover or master-slave 48 | replication. You have already seen one particular form of failover: the ability 49 | to restart a component means that after a failure, a new instance is created 50 | and takes over functionality, like passing the baton from one runner to the 51 | next. For a stateful service, the new instance accesses the same persistent 52 | storage location as the previously failed one, recovering the state before the 53 | crash and continuing from there. This works only as long as the persistent 54 | storage is intact; if that fails, then restarting is not possible—the service 55 | will forget all of its previous state and start from scratch. Imagine your web 56 | shop forgetting about all registered users—that would be a catastrophe!
57 | 58 | 59 | 60 |“A component shall do only one thing, but do it in full.”
46 | 47 |This pattern applies wherever a system performs multiple functions or the 48 | functions it performs are so complex that they need to be broken into different 49 | components. An example is a text editor that includes spell checking: these are 50 | two separate functions (editing can be done without spell checking, and 51 | spelling can also be checked on the finished text and does not require editing 52 | capabilities), but on the other hand, neither of these functions is trivial.
53 | 54 |The Simple Component pattern derives from the single responsibility 55 | principle that was formulated by Tom DeMarco in his 1979 book Structured 56 | Analysis and System Specification (Prentice Hall). In its abstract form, it 57 | demands to “maximize cohesion and minimize coupling.” Applied to 58 | object-oriented software design, it is usually stated as follows: “A class 59 | should have only one reason to change.”
60 | 61 | 62 | 63 |Working with strictly typed actor references benefits from some new facilities:
51 | 52 |These factilities are introduced in this lecture.
60 | 61 | 65 |“Publish the events emitted by a component so that the rest of the system can derive knowledge from them.”
46 | 47 |The events that a component stores in its log represent the sum of all the 48 | knowledge it has ever possessed. This is a treasure trove for the rest of the 49 | system to delve into: although the shopping cart system is only interested in 50 | maintaining the current state of customer activity, other concerns are 51 | tangential to it, such as tracking the popularity of various products. This 52 | secondary concern does not need to be updated in a guaranteed fashion in real 53 | time; it does not matter if it lags behind the most current information by a 54 | few seconds (individual humans usually would not be able to notice even a delay 55 | of hours in this information). Therefore, it would be an unnecessary burden to 56 | have the shopping cart component provide this summary information, and it would 57 | also violate the Simple Component pattern by introducing a second 58 | responsibility.
59 | 60 | 61 | 62 |This lecture goes deeper on how the Akka Cluster works. In particular you will see:
51 | 52 |The effects are demonstrated on the link checker example as well.
58 | 59 | 63 |“Dropping requests is preferable to failing uncontrollably.”
46 | 47 |Imagine a system that is exposed to uncontrollable user input (for example, a 48 | site on the internet). Any deployment will be finite in both its processing 49 | capability and its buffering capacity, and if user input exceeds the former for 50 | long enough, the latter will be used up and something will need to fail. If 51 | this is not foreseen explicitly, then an automatic out-of-memory killer will 52 | make a decision that is likely to be less satisfactory than a planned 53 | load-shedding mechanism—and shedding load means dropping requests.
54 | 55 |This is more of a philosophy than an implementation pattern. Network protocols, 56 | operating systems, programming platforms, and libraries will all drop packets, 57 | messages, or requests when overloaded; they do so in order to protect the 58 | system so that it can recover when load decreases. In the same spirit, authors 59 | of Reactive systems need to be comfortable with the notion of sometimes 60 | deliberately losing messages.
61 | 62 | 63 | 64 |This lecture discusses scalability, starting out from contrasting this characteristic with performance—the goal that is often inadequately placed first. We cover:
51 | 52 |“Keep multiple copies of a service running in different locations, and perform all modifications at all of them.”
46 | 47 |With multiple-master replication patterns, you achieved resilience for the 48 | storage subsystem of the example batch job processing facility by replicating 49 | it across different locations (data centers, availability zones, and so on). 50 | You saw that you can achieve strong consistency only when implementing a 51 | failover mechanism; both CRDT-based replication and conflict detection avoid 52 | this at the cost of not guaranteeing full consistency. One property of failover 53 | is that it takes some time: first, you need to detect that there is trouble, 54 | and then, you must establish consensus about how to fix it—for example, by 55 | switching to another replica. Both activities require communication and 56 | therefore cannot be completed instantaneously. Where this is not tolerable, you 57 | need a different strategy, but because there is no magic bullet, you must 58 | expect different restrictions.
59 | 60 | 61 | 62 |This lecture gives a more formal introduction to the Actor model. In particular we cover:
51 | 52 |The video concludes with a demonstration of running an Actor System and a summary of what Actors are according to the formal model.
61 | 62 | 66 |This lecture sets the stage for the Akka Typed week: we explore how to express 51 | a communication protocol such that a machine can understand the message 52 | exchange — meaning who shall send which message type and when. In particular we 53 | discuss session types, consisting of a global type that describes the whole 54 | interaction at once, and local projections that specify the expected sequence 55 | of send and receive operations for any single party in isolation.
56 | 57 | 61 |“Each message will contain all information needed to process a request as well as to understand its response.”
46 | 47 |When sending a request, you need to remember what you want to do with the 48 | response that will eventually come back. In other words, you need to manage the 49 | state of the larger operation that this exchange is a part of while the request 50 | and response travel between components. This state management can be done 51 | entirely by the requester—storing contextual information—or it can be pushed 52 | out of it by having the entire context travel with the request and response 53 | across the network. In practice, this responsibility is usually shared, leaving 54 | part of the state in the requester and having part of it travel with the 55 | message. The point of this pattern is that you should strive to include 56 | sufficient information in the message so the state that is relevant to the 57 | current request is fully represented—removing and relocating relevant 58 | information should be considered a premature optimization until proven 59 | otherwise.
60 | 61 | 62 | 63 |“Send compound instructions to the resource to avoid excessive network usage.”
46 | 47 |You have encapsulated the resources your system uses in components that manage, 48 | represent, and directly implement their functionality. This allows you to 49 | confine responsibility not only for code-modularity reasons (chapter 6) but 50 | also for vertical and horizontal scalability (chapters 4 and 5) and principled 51 | failure handling (chapter 7). The price of all these advantages is that you 52 | introduce a boundary between the resource and the rest of the system that can 53 | only be crossed by asynchronous messaging. The Resource Loan pattern may help 54 | to move a resource as close as possible to its users, but this barrier will 55 | remain, leading to increased latency and, usually, decreased communication 56 | bandwidth. The core of the Complex Command pattern lies in sending the behavior 57 | to the resource in order to save time and network bandwidth in case of 58 | loquacious interchanges between resource and users; the user of the resource is 59 | only interested in the comparatively small result.
60 | 61 | 62 | 63 |“Scale out the management of a large number of domain objects by grouping them into shards based on unique and stable object properties.”
46 | 47 |The Domain Object pattern gives you the ability to wrap 48 | the domain’s state in small components that can, in principle, be distributed 49 | easily across a cluster of network nodes in order to provide the resources for 50 | representing even very large domains that cannot be held in memory by a single 51 | machine. The difficulty then becomes how to address the individual domain 52 | objects without having to maintain a directory that lists every object’s 53 | location—such a directory could easily reach a size that is impractical to hold 54 | in memory.
55 | 56 |The Sharding pattern places an upper bound on the size of the directory by 57 | grouping the domain objects into a configurable number of shards—the domain is 58 | fractured algorithmically into pieces of manageable size. The term 59 | algorithmically means the association between objects and shards is determined 60 | by a fixed formula that can be evaluated whenever an object needs to be 61 | located.
62 | 63 | 64 | 65 |“Divide long-lived, distributed transactions into quick local ones with compensating actions for recovery.”
46 | 47 |The term saga was coined by Hector Garcia-Molina. His paper describes a scheme 48 | for breaking up long-lived business transactions in order to shorten the time 49 | period during which databases need to hold locks—these locks are needed to 50 | ensure atomicity and consistency of the transaction, the downside of which is 51 | that other transactions touching the same data cannot proceed concurrently.
52 | 53 |In a distributed system, you need to break up transactions involving multiple 54 | participants for other reasons: obtaining a shared lock is an expensive 55 | operation that can even be impossible in the face of certain failures like 56 | network partitions. As we discussed in chapter 8, the key to scalability and 57 | loose coupling is to consider each component an island of delimited 58 | consistency. But how do you model business transactions that require inputs 59 | from multiple components while also effecting modifications to multiple 60 | components? It turns out the research topic of sagas provides an effective, 61 | robust solution for many use cases.
62 | 63 | 64 | 65 |This lecture discusses how supervision in Akka Typed differs from the 51 | previously discussed supervision implemented in untyped Akka actors:
52 | 53 |The interesting part is that supervision is implemented as a purely functional 60 | behavior decorator, show-casing how libraries can add powerful capabilities to 61 | the Akka Typed system.
62 | 63 | 67 |“Protect services by breaking the connection to their users during prolonged failure conditions.”
46 | 47 |In previous patterns, we discussed how to segregate a system into a hierarchy 48 | of components and subcomponents for the purpose of isolating responsibilities 49 | and encapsulating failure domains. This pattern describes how to safely connect 50 | different parts of the system so that failures do not spread uncontrollably 51 | across them. Its origin lies in electrical engineering: in order to protect 52 | electrical circuits from each other and introduce decoupled failure domains, a 53 | technique was established of breaking the connection when the transmitted power 54 | exceeds a given threshold.
55 | 56 |Translated to a Reactive application, this means the flow of requests from one 57 | component to the next may be broken up deliberately when the recipient is 58 | overloaded or otherwise failing. Doing so serves two purposes: first, the 59 | recipient gets some breathing room to recover from possible load-induced 60 | failures; and second, the sender decides that requests will fail instead of 61 | wasting time with waiting for negative replies.
62 | 63 | 64 | 65 |“Include identifying and/or sequencing information in the message, and keep retrying until confirmation is received.”
46 | 47 |While discussing the Saga pattern, we made the implicit assumption that 48 | communication between the saga and the affected components is reliable. We 49 | pictured a group of people standing in the same office and discussing the 50 | process without external disturbances. This is a useful way to begin, because 51 | it allows you to focus on the essential parts of a conversation; but we know 52 | that life does not always work like that—in particular in distributed systems, 53 | where messages can be lost or delayed due to unforeseeable, inexorable 54 | subsystem failures.
55 | 56 |Fortunately, we can treat the two concerns on separate levels: imagining that 57 | the conversation occurs in a busy, noisy office does not invalidate the basic 58 | structure of the business process we are modeling. All that is needed is to 59 | deliver every message more carefully, transmitting it again if it is 60 | overshadowed by some other event. This second level is what the Business 61 | Handshake pattern is all about.
62 | 63 | 64 | 65 |“Hide an elastic pool of resources behind their owner.”
46 | 47 |So far, we have discussed the modeling and operation of a single resource as 48 | well as its interaction with its clients. The astute reader will have noticed 49 | that something is missing from the full picture: the core principles of 50 | Reactive system design demand replication. Recalling the discussion from 51 | chapter 2, you know that resilience cannot be achieved without distributing the 52 | solution across all failure axes—software, hardware, human—and you know that 53 | elasticity requires the ability to distribute the processing load across a 54 | number of resources that are dynamically adjusted to the incoming demand.
55 | 56 |In chapter 13, you learned about different ways to replicate a component. The 57 | effort put into this mechanism depends greatly on how much the component’s 58 | state needs to be synchronized between replicas. This pattern focuses on the 59 | management and external presentation of the replicas. In keeping with the 60 | reasoning presented in chapters 4 and 5, it relies heavily on asynchronous 61 | message passing and location transparency to achieve scalability.
62 | 63 | 64 | 65 |“Prefer a full component restart to internal failure handling.”
46 | 47 |In chapter 7 of the book we discuss principled failure handling, noting that the 48 | internal recovery mechanisms of each component are limited because they are not 49 | sufficiently separated from the failing parts—everything within a component can 50 | be affected by a failure. This is especially true for hardware failures that 51 | take down the component as a whole, but it is also true for corrupted state 52 | that is the result of some programming error only observable in rare 53 | circumstances. For this reason, it is necessary to delegate failure handling to 54 | a supervisor instead of attempting to solve it within the component.
55 | 56 |This principle is also called crash-only software: the idea is that transient 57 | but rare failures are often costly to diagnose and fix, making it preferable to 58 | recover a working system by rebooting parts of it. This hierarchical 59 | restart-based failure handling makes it possible to greatly simplify the 60 | failure model and at the same time leads to a more robust system that even has 61 | a chance to survive failures that were entirely unforeseen.
62 | 63 | 64 | 65 |Akka Typed is an evolution of the untyped Akka actor implementation to support
51 | channel types: most importantly, the ActorRef now is parameterized with the
52 | type of messages it accepts. This has several other consequences that we
53 | discuss in this lecture.
The use of more precise types within actor interactions is then demonstrated on 56 | a small example, including how to set up a typed actor system and how to handle 57 | fully typed responses, i.e. continuations of the protocol throughout the full 58 | interchange.
59 | 60 | 64 |This lecture takes note of the fact that all communication in a distributed system takes time—there is no instantaneous understanding of what a remote component is currently doing. We discuss this starting out from locally implemented strong consistency:
51 | 52 |“Include a return address in the message to receive a response.”
46 | 47 |This is the most basic interaction pattern we know; it is the foundational 48 | building block for all natural communication, deeply ingrained in human 49 | training. A parent will say something to their infant child, who will initially 50 | gesture or make some sounds in response; later, the child will articulate words 51 | and sentences. Request-response is the way you learn how to speak, and it 52 | underlies all sophisticated forms of communication that you develop later. 53 | Although the response can be nonverbal (in particular, facial expressions, but 54 | also the deliberate absence thereof), in most cases you require a response 55 | before successfully concluding a conversation. The response can be a piece of 56 | information that you asked for or an acknowledgment of receipt for a command 57 | that was given.
58 | 59 |In all these cases, there is one commonality that you need to make explicit 60 | when translating this basic means of communication into a programming pattern: 61 | the process begins with two participants A and B, where A knows how to address 62 | B; when receiving requests, B will need to learn or deduce how to address A in 63 | order to send back a response.
64 | 65 | 66 | 67 |In this lecture we take a deeper look at how Actors function. This is fundamentally defined by how they are processing messages. After revisiting their encapsulated nature we cover:
51 | 52 |These aspects are demonstrated on the bank account transfer process that was used in the first lecture to demonstrate race conditions and deadlocks. We conclude by enumerating the key effects of focusing on message-passing.
60 | 61 | 65 |“A resource and its lifecycle are responsibilities that must be owned by one component.”
46 | 47 |From the Simple Component pattern, you know that every 48 | component does only one thing, but does it in full; in other words, each 49 | component is fully responsible for the functionality it provides to the rest of 50 | the system. If we regard that functionality as a resource that is used by other 51 | components—inside or outside the system—then it is clear that resource, 52 | responsibility, and component exactly coincide. These three terms all denote 53 | the same boundary: in this view, resource encapsulation and the single 54 | responsibility principle are the same. The same reasoning can be applied when 55 | considering other resources, in particular those used to provide a component’s 56 | function. These are not implemented but merely are managed or represented: the 57 | essence of the Resource Encapsulation pattern is that you must identify that 58 | component into whose responsibility each resource falls, and place it there. 59 | The resource becomes part of that component’s responsibility. Sometimes this 60 | will lead you to identify the management of an external resource as a notable 61 | responsibility that needs to be broken out into its own simple component.
62 | 63 | 64 | 65 |This lecture treats the most important characteristic of Actors, namely how they support handling failures in a principled fashion. Due to their encapsulation, failure is contained within the compartment of the system that is represented by each Actor. We therefore cover:
51 | 52 |We summarize these learnings by drawing a diagram of the Actor lifecycle.
61 | 62 | 66 |This lecture completes the first walkthrough of how to use Actors by introducing the means for testing them. Due to their encapsulation, testing Actors is approached differently from traditional OO testing—mocks cannot be used to deeply introspect their behavior. We will cover:
51 | 52 |After viewing this lecture you will be well-equipped for the first exercise.
60 | 61 | 65 |In this lecture we build upon what we learned about an Actor’s lifecycle and introduce facilities for monitoring it. We then discuss the consequences of hierarchical supervision for the architecture of our system. In particular we cover:
51 | 52 |In this lecture we build an Actor-based link checker application in which multiple actors collaborate. On this example we see how:
51 | 52 |Along this journey we find ourselves considering the interplay between Actor code and other concurrency abstractions, in particular considering where we must be careful so that the Actor encapsulation is not broken. We also see how the use of immutable data structures helps avoid mistakes in this regard.
60 | 61 | 65 |This lecture treats the storage of persistent state for Actors. It starts out from a comparison between in-place updates and an append-only event log (event-sourcing). In particular we cover:
51 | 52 |We conclude this lecture by discussing when and how to perform non-idempotent external effects from your Actors.
61 | 62 | 66 |In this final lecture we discuss the means and tradeoffs involved in achieving the responsiveness that is required of our systems. In particular, we cover:
51 | 52 |In summary, we reach the conclusion that message-driven systems can be scaled vertically and horizontally, and that responsiveness requires both resilience and elasticity.
60 | 61 | 65 |“Give a client exclusive transient access to a scarce resource without transferring ownership.”
46 | 47 |A variant of the Resource Loan pattern is widely used in 48 | non-Reactive systems, the most prominent example being that of a database 49 | connection pool. Database access is represented by a connection object via 50 | which arbitrary operations can be performed. The creation of connections is 51 | expensive, and their number is limited; therefore, a connection is not owned by 52 | client code but is taken from a pool before performing an operation and put 53 | back afterward. The connection pool is responsible for managing the lifecycle 54 | of its connections, and client code obtains temporary permission to use them. 55 | Failures in this scenario are communicated to the client, but their effect on 56 | the connection in question is handled by the pool—the pool owns and supervises 57 | the connections.
58 | 59 |In a Reactive system, you strive to minimize contention as well as the need for 60 | coordination: hence, the classic database connection pool usually only features 61 | as an internal implementation detail of a component whose data storage is 62 | realized by means of a relational database. But you will frequently encounter 63 | the use of scarce resources in your systems, and the same philosophy that 64 | drives the connection pool abstraction is useful in Reactive system design as 65 | well.
66 | 67 | 68 | 69 |