Reactive Design Patterns
Roland Kuhn with Brian Hanafee and Jamie Allen
Foreword by Jonas Bonér
  • February 2017
  • ISBN 9781617291807
  • 392 pages
  • printed in black & white

Does an excellent job explaining Reactive architecture and design, starting with first principles and putting them into a practical context.

From the Foreword by Jonas Boner, Creator of Akka

Reactive Design Patterns is a clearly written guide for building message-driven distributed systems that are resilient, responsive, and elastic. In this book you'll find patterns for messaging, flow control, resource management, and concurrency, along with practical issues like test-friendly designs. All patterns include concrete examples using Scala and Akka.

Table of Contents detailed table of contents

Part 1: Introduction

1. Why Reactive?

1.1. The anatomy of a Reactive application

1.2. Coping with load

1.3. Coping with failures

1.4. Making it responsive

1.5. Avoiding the ball of mud

1.6. Integrating non-reactive components

1.7. Summary

2. A walk-through of the Reactive manifesto

2.1. Reacting to Users

2.1.1. Understanding the Traditional Approach

2.1.2. Analyzing Latency with a Shared Resource

2.1.3. Limiting Maximum Latency with a Queue

2.2. Exploiting Parallelism

2.2.1. Reducing Latency by Parallelization

2.2.2. Improving with Composable Futures

2.2.3. Paying for the Serial Illusion

2.3. The Limits of Parallel Execution

2.3.1. Amdahl's Law

2.3.2. Universal Scalability Law

2.4. Reacting to Failure

2.4.1. Compartmentalization and Bulkheading

2.4.2. Using Circuit Breakers

2.4.3. Supervision

2.5. Losing Strong Consistency

2.5.1. ACID 2.0

2.5.2. Accepting Updates

2.6. The Need for Reactive Design Patterns

2.6.1. Managing Complexity

2.6.2. Bringing Programming Models Closer to the Real World

2.7. Summary

3. Tools of the Trade

3.1. Early Reactive Solutions

3.2. Functional Programming

3.2.1. Immutability

3.2.2. Side Effects

3.2.3. Referential Transparency

3.2.4. Functions as First-Class Citizens

3.3. Responsiveness to Users

3.3.1. Prioritizing the Three Performance Characteristics

3.4. Implementations That Support Reactive

3.4.1. Green Threads

3.4.2. Event Loops

3.4.3. Communicating Sequential Processes

3.4.4. Futures and Promises

3.4.5. Reactive Extensions

3.4.6. The Actor Model

3.4.7. Summary

Part 2: The Philosophy in a Nutshell

4. Message Passing

4.1. Messages

4.2. Vertical Scalability

4.3. Event-Based vs. Message-Based

4.4. Synchronous vs. Asynchronous

4.5. Flow Control

4.6. Delivery Guarantees

4.7. Vertical Scalability

4.8. Events as Messages

4.9. Synchronous Message Passing

4.10. Summary

5. Location Transparency

5.1. What is Location Transparency?

5.2. The Fallacy of Transparent Remoting

5.3. Explicit Message Passing to the Rescue

5.4. The Role of Latency and Throughput

5.5. The Role of Message Loss

5.6. Horizontal Scalability

5.7. Location Transparency makes Testing Simpler

5.8. Dynamic Composition

5.9. Summary

6. Divide and Conquer

6.1. Hierarchical Problem Decomposition

6.1.1. Defining the hierarchy

6.2. Dependencies vs. Descendant Modules

6.2.1. Avoiding the matrix

6.3. Advantages for Specification and Test

6.4. Build your own Big Corporation

6.5. Horizontal and Vertical Scalability

6.6. Summary

7. Principled Failure Handling

7.1. Ownership means Commitment

7.2. Ownership implies Lifecycle Control

7.3. Resilience on All Levels

7.4. Summary

8. Delimited Consistency

8.1. Encapsulated Modules to the Rescue

8.2. Grouping Data and Behavior According to Transaction Boundaries

8.3. Modeling Work-flows across Transactional Boundaries

8.4. Unit of Failure = Unit of Consistency

8.5. Segregation of Responsibilities

8.6. Persisting Isolated Scopes of Consistency

8.7. Summary

9. Non-Determinism by Need

9.1. Logic Programming and Declarative Data-Flow

9.2. Functional Reactive Programming

9.3. Shared-Nothing Concurrency

9.4. Shared-State Concurrency

9.5. So, What Should We Do?

9.6. Summary

10. Message Flow

10.1. Push Data Forward

10.2. Model the Processes of Your Domain

10.3. Identify Resilience Limitations

10.4. Estimate Rates and Deployment Scale

10.5. Plan for Flow Control

10.6. Summary for Part 2

Part 3: Patterns

11. Testing Reactive Applications

11.1. How To Test

11.1.1. Unit Tests

11.1.2. Component Tests

11.1.3. String Tests

11.1.4. Integration Tests

11.1.5. User Acceptance Tests

11.1.6. Black Box Versus White Box Tests

11.2. Test Environment

11.3. Testing Asynchronously

11.3.1. Providing Blocking Message Receivers

11.3.2. The Crux with Choosing Timeouts

11.3.3. Asserting the Absence of a Message

11.3.4. Providing Synchronous Execution Engines

11.3.5. Asynchronous Assertions

11.3.6. Fully Asynchronous Tests

11.3.7. Asserting the Absence of Asynchronous Errors

11.4. Testing Non-Deterministic Systems

11.4.1. The Trouble with Execution Schedules

11.4.2. Testing Distributed Components

11.4.3. Mocking Actors

11.4.4. Distributed Components

11.5. Testing Elasticity

11.6. Testing Resilience

11.6.1. Application Resilience

11.6.2. Infrastructure Resilience

11.7. Testing Responsiveness

11.8. Summary

12. Fault Tolerance and Recovery Patterns

12.1. The Simple Component Pattern

12.1.1. The Problem Setting

12.1.2. Applying the Pattern

12.1.3. The Pattern Revisited

12.1.4. Applicability

12.2. The Error Kernel Pattern

12.2.1. The Problem Setting

12.2.2. Applying the Pattern

12.2.3. The Pattern Revisited

12.2.4. Applicability

12.3. The Let-It-Crash Pattern

12.3.1. The Problem Setting

12.3.2. Applying the Pattern

12.3.3. The Pattern Revisited

12.3.4. Implementation Considerations

12.3.5. Corollary: the Heartbeat Pattern

12.3.6. Corollary: The Proactive Failure Signal Pattern

12.4. The Circuit Breaker Pattern

12.4.1. The Problem Setting

12.4.2. Applying The Pattern

12.4.3. The Pattern Revisited

12.4.4. Applicability

12.5. Summary

13. Replication Patterns

13.1. The Active—Passive Replication Pattern

13.1.1. The Problem Setting

13.1.2. Applying The Pattern

13.1.3. The Pattern Revisited

13.1.4. Applicability

13.2. Multiple-Master Replication Patterns

13.2.1. Consensus-Based Replication

13.2.2. Replication with Conflict Detection and Resolution

13.2.3. Conflict-Free Replicated Data Types

13.3. The Active—Active Replication Pattern

13.3.1. The Problem Setting

13.3.2. Applying The Pattern

13.3.3. The Pattern Revisited

13.3.4. The Relation to Virtual Synchrony

13.4. Summary

14. Resource Management Patterns

14.1. Resource Encapsulation Pattern

14.1.1. The Problem Setting

14.1.2. Applying the Pattern

14.1.3. The Pattern Revisited

14.1.4. Applicability

14.2. Resource Loan Pattern

14.2.1. The Problem Setting

14.2.2. Applying the Pattern

14.2.3. The Pattern Revisited

14.2.4. Applicability

14.2.5. Implementation Considerations

14.2.6. Variant: using the Resource Loan pattern for partial exposure

14.3. The Complex Command Pattern

14.3.1. The Problem Setting

14.3.2. Applying the Pattern

14.3.3. The Pattern Revisited

14.3.4. Applicability

14.4. The Resource Pool Pattern

14.4.1. The Problem Setting

14.4.2. Applying the Pattern

14.4.3. The Pattern Revisited

14.4.4. Implementation Considerations

14.5. Patterns for Managed Blocking

14.5.1. The Problem Setting

14.5.2. Applying the Pattern

14.5.3. The Pattern Revisited

14.5.4. Applicability

14.6. Summary

15. Message Flow Patterns

15.1. The Request—Response Pattern

15.1.1. The Problem Setting

15.1.2. Applying the Pattern

15.1.3. Common Instances of the Pattern

15.1.4. The Pattern Revisited

15.1.5. Applicability

15.2. The Self-Contained Message Pattern

15.2.1. The Problem Setting

15.2.2. Applying the Pattern

15.2.3. The Pattern Revisited

15.2.4. Applicability

15.3. The Ask Pattern

15.3.1. The Problem Setting

15.3.2. Applying the Pattern

15.3.3. The Pattern Revisited

15.3.4. Applicability

15.4. The Forward Flow Pattern

15.4.1. The Problem Setting

15.4.2. Applying the Pattern

15.4.3. The Pattern Revisited

15.4.4. Applicability

15.5. The Aggregator Pattern

15.5.1. The Problem Setting

15.5.2. Applying the Pattern

15.5.3. The Pattern Revisited

15.5.4. Applicability

15.6. The Saga Pattern

15.6.1. The Problem Setting

15.6.2. Applying the Pattern

15.6.3. The Pattern Revisited

15.6.4. Applicability

15.7. The Business Handshake Pattern

15.7.1. The Problem Setting

15.7.2. Applying the Pattern

15.7.3. The Pattern Revisited

15.7.4. Applicability

15.8. Summary

16. Flow Control Patterns

16.1. The Pull Pattern

16.1.1. The Problem Setting

16.1.2. Applying the Pattern

16.1.3. The Pattern Revisited

16.1.4. Applicability

16.2. The Managed Queue Pattern

16.2.1. The Problem Setting

16.2.2. Applying the Pattern

16.2.3. The Pattern Revisited

16.2.4. Applicability

16.3. The Drop Pattern

16.3.1. The Problem Setting

16.3.2. Applying the Pattern

16.3.3. The Pattern Revisited

16.3.4. Applicability

16.4. The Throttling Pattern

16.4.1. The Problem Setting

16.4.2. Applying the Pattern

16.4.3. The Pattern Revisited

16.5. Summary

17. State Management and Persistence Patterns

17.1. The Domain Object Pattern

17.1.1. The Problem Setting

17.1.2. Applying the Pattern

17.1.3. The Pattern Revisited

17.2. The Sharding Pattern

17.2.1. The Problem Setting

17.2.2. Applying the Pattern

17.2.3. The Pattern Revisited

17.2.4. Important Caveat

17.3. The Event-Sourcing Pattern

17.3.1. The Problem Setting

17.3.2. Applying the Pattern

17.3.3. Revisiting the Pattern

17.3.4. Applicability

17.4. The Event Stream Pattern

17.4.1. The Problem Setting

17.4.2. Applying the Pattern

17.4.3. The Pattern Revisited

17.4.4. Applicability

17.5. Summary

Appendixes

Appendix A: Diagramming Reactive Systems

A.1. Defining the Stencils

Appendix B: An Illustrated Example

B.1. Geographic Partitioning

B.2. Planning the Flow of Information

B.2.1. First Step: Accepting the Data

B.2.2. Second Step: Getting the Data to their Geographical Home

B.2.3. Step Three: Relocating the Data for Efficient Querying

B.2.4. Taking Stock

B.3. What if something fails?

B.3.1. A Client Fails

B.3.3. A Data Ingestion Front-End Node Fails

B.3.5. A Map Tile Processing Node Fails

B.3.6. A Summary Map Tile Fails

B.3.8. A Map View Front-End Node Fails

B.3.9. Failure Handling Summary

B.4. What have we learnt from this example?

B.5. Where do we go from here?

Appendix C: The Reactive Manifesto

C.1. Main text

C.2. Glossary

C.2.1. Asynchronous

C.2.2. Back-Pressure

C.2.3. Batching

C.2.4. Component

C.2.5. Delegation

C.2.6. Elasticity (in contrast to Scalability)

C.2.7. Failure (in contrast to Error)

C.2.8. Isolation (and Containment)

C.2.9. Location Transparency

C.2.10. Message-Driven (in contrast to Event-Driven)

C.2.11. Non-Blocking

C.2.12. Protocol

C.2.13. Replication

C.2.14. Resource

C.2.15. Scalability

C.2.16. System

C.2.17. User

About the Technology

Modern web applications serve potentially vast numbers of users - and they need to keep working as servers fail and new ones come online, users overwhelm limited resources, and information is distributed globally. A Reactive application adjusts to partial failures and varying loads, remaining responsive in an ever-changing distributed environment. The secret is message-driven architecture - and design patterns to organize it.

About the book

Reactive Design Patterns presents the principles, patterns, and best practices of Reactive application design. You'll learn how to keep one slow component from bogging down others with the Circuit Breaker pattern, how to shepherd a many-staged transaction to completion with the Saga pattern, how to divide datasets by Sharding, and more. You'll even see how to keep your source code readable and the system testable despite many potential interactions and points of failure.

What's inside

  • The definitive guide to the Reactive Manifesto
  • Patterns for flow control, delimited consistency, fault tolerance, and much more
  • Hard-won lessons about what doesn't work
  • Architectures that scale under tremendous load

About the reader

Most examples use Scala, Java, and Akka. Readers should be familiar with distributed systems.

About the authors

Dr. Roland Kuhn led the Akka team at Lightbend and coauthored the Reactive Manifesto. Brian Hanafee and Jamie Allen are experienced distributed systems architects.


Buy
combo $49.99 pBook + eBook + liveBook
eBook $39.99 pdf + ePub + kindle + liveBook
Already own this book?
You can add audio for liveBook from your bookshelf!

FREE domestic shipping on three or more pBooks

If the 'Reactive Manifesto' gave us a battle cry, this work gives us the strategic handbook for battle.

Joel Kotarski, The Rawlings Group

An engaging tour of distributed computing and the building blocks of responsive, resilient software.

William Chan, LinkedIn

This book is so reactive, it belongs on the left-hand side of the periodic table!

Andy Hicks, Tanis Systems