SlideShare a Scribd company logo
Reactive Design
Patterns
Dr. Roland Kuhn
@rolandkuhn — CTO Actyx AG
Reactive Design Patterns
• currently in MEAP
• all chapters done,

in pre-production
• use code 39kuhn (39% off),

see http://rolandkuhn.com
2
Reactive?
Elasticity: Performance at Scale
4
Resilience: Don’t put all eggs in one basket!
5
Result: Responsiveness
• elastic components that scale with their load
• responses in the presence of partial failures
6
Result: Decoupling
• containment of
• failures
• implementation details
• responsibility
• shared-nothing architecture, clear boundaries
7
Result: Maintainability & Fexibility
• decoupled responsibility—decoupled teams
• develop pieces at their own pace
• continuous delivery
• Microservices: Single Responsibility Principle
8
Implementation: Message-Driven
• focus on communication between
components
• model message flows and protocols
• common transports: async HTTP, *MQ, Actors
9
Reactive Traits
10
elastic resilient
responsive maintainable extensible
message-­‐driven
Value
Means
Form
Architecture Patterns
Basically: Microservices Best Practices
• Simple Component Pattern
• DeMarco in «Structured analysis and system specification»
(Yourdon, New York, 1979)
• “maximize cohesion and minimize coupling”
• Let-It-Crash Pattern
• Candea & Fox: “Crash-Only Software” (USENIX HotOS IX,
2003)
• Error Kernel Pattern
• Erlang (late 1980’s)
12
Implementation Patterns
Request–Response Pattern
14
«Include a return address in the message
in order to receive a response.»
Request–Response Pattern
15
Request–Response Pattern
• return address is often implicit:
• HTTP response over same TCP connection
• automatic sender reference capture in Akka
• explicit return address is needed otherwise
• *MQ
• Akka Typed
• correlation ID needed for long-lived participants
16
Circuit Breaker Pattern
17
«Protect services by breaking the
connection during failure periods.»
Circuit Breaker Pattern
• well-known, inspired by electrical engineering
• first published by M. Nygard in «Release It!»
• protects both ways:
• allows client to avoid long failure timeouts
• gives service some breathing room to recover
18
Circuit Breaker Example
19
private object StorageFailed extends RuntimeException
private def sendToStorage(job: Job): Future[StorageStatus] = {
// make an asynchronous request to the storage subsystem
val f: Future[StorageStatus] = ???
// map storage failures to Future failures to alert the breaker
f.map {
case StorageStatus.Failed => throw StorageFailed
case other => other
}
}
private val breaker = CircuitBreaker(
system.scheduler, // used for scheduling timeouts
5, // number of failures in a row when it trips
300.millis, // timeout for each service call
30.seconds) // time before trying to close after tripping
def persist(job: Job): Future[StorageStatus] =
breaker
.withCircuitBreaker(sendToStorage(job))
.recover {
case StorageFailed => StorageStatus.Failed
case _: TimeoutException => StorageStatus.Unknown
case _: CircuitBreakerOpenException => StorageStatus.Failed
}
Multiple-Master Replication Patterns
20
«Keep multiple distributed copies,

accept updates everywhere,

disseminate updates among replicas.»
Multiple-Master Replication Patterns
• this is a tough problem with no perfect solution
• requires a trade-off to be made between
consistency and availability
• consensus-based focuses on consistency
• conflict-free focuses on availability
• conflict resolution gives up a bit of both
• each requires a different programming model
and can express different transactional behavior
21
Consensus-Based Replication
• strong coupling between replicas to ensure
that all are “on the same page”
• unavailable during network outages or certain
machine failures
• programming model “just like a single thread”
• Postgres, Zookeeper, etc.
22
Replication with Conflict Resolution
• requires conflict detection
• resolution without user intervention will have to
discard some updates
• detection/resolution unavailable during partitions
• programming model “like single thread” with
caveat
• popular RDBMS in default configuration offer this
23
Conflict-Free Replication
• express updates such that they can be merged
• cannot express “non-local” constraints
• all expressible updates can be performed under
any conditions without losses or inconsistencies
• replicas may temporarily be out of sync
• different programming model, explicitly distributed
• Riak 2.0, Akka Distributed Data
24
Multiple-Master Replication Patterns
• no one size fits all
• you will have to think and decide!
25
Saga Pattern
26
«Divide long-lived distributed
transactions into quick local ones with
compensating actions for recovery.»
Saga Pattern: Background
• Microservice Architecture means distribution
of knowledge, no more central database
instance
• Pat Helland:
• “Life Beyond Distributed Transactions”, CIDR 2007
• “Memories, Guesses, and Apologies”, MSDN blog 2007
• What about transactions that affect multiple
microservices?
27
Saga Pattern
• Garcia-Molina & Salem: “SAGAS”, ACM, 1987
• Bank transfer avoiding lock of both accounts:
• T₁: transfer money from X to local working account
• T₂: transfer money from local working account to Y
• C₁: compensate failure by transferring money back to X
• Compensating transactions are executed during
Saga rollback
• concurrent Sagas can see intermediate state
28
Saga Pattern
• backward recovery:

T₁ T₂ T₃ C₃ C₂ C₁
• forward recovery with save-points:

T₁ (sp) T₂ (sp) T₃ (sp) T₄
• in practice Sagas need to be persistent to
recover after hardware failures, meaning
backward recovery will also use save-points
29
Example: Bank Transfer
30
trait Account {
def withdraw(amount: BigDecimal, id: Long): Future[Unit]
def deposit(amount: BigDecimal, id: Long): Future[Unit]
}
case class Transfer(amount: BigDecimal, x: Account, y: Account)
sealed trait Event
case class TransferStarted(amount: BigDecimal, x: Account, y: Account) extends Event
case object MoneyWithdrawn extends Event
case object MoneyDeposited extends Event
case object RolledBack extends Event
Example: Bank Transfer
31
class TransferSaga(id: Long) extends PersistentActor {
import context.dispatcher
override val persistenceId: String = s"transaction-$id"
override def receiveCommand: PartialFunction[Any, Unit] = {
case Transfer(amount, x, y) =>
persist(TransferStarted(amount, x, y))(withdrawMoney)
}
def withdrawMoney(t: TransferStarted): Unit = {
t.x.withdraw(t.amount, id).map(_ => MoneyWithdrawn).pipeTo(self)
context.become(awaitMoneyWithdrawn(t.amount, t.x, t.y))
}
def awaitMoneyWithdrawn(amount: BigDecimal, x: Account, y: Account): Receive = {
case m @ MoneyWithdrawn => persist(m)(_ => depositMoney(amount, x, y))
}
...
}
Example: Bank Transfer
32
def depositMoney(amount: BigDecimal, x: Account, y: Account): Unit = {
y.deposit(amount, id) map (_ => MoneyDeposited) pipeTo self
context.become(awaitMoneyDeposited(amount, x))
}
def awaitMoneyDeposited(amount: BigDecimal, x: Account): Receive = {
case Status.Failure(ex) =>
x.deposit(amount, id) map (_ => RolledBack) pipeTo self
context.become(awaitRollback)
case MoneyDeposited =>
persist(MoneyDeposited)(_ => context.stop(self))
}
def awaitRollback: Receive = {
case RolledBack =>
persist(RolledBack)(_ => context.stop(self))
}
Example: Bank Transfer
33
override def receiveRecover: PartialFunction[Any, Unit] = {
var start: TransferStarted = null
var last: Event = null
{
case t: TransferStarted => { start = t; last = t }
case e: Event => last = e
case RecoveryCompleted =>
last match {
case null => // wait for initialization
case t: TransferStarted => withdrawMoney(t)
case MoneyWithdrawn => depositMoney(start.amount, start.x, start.y)
case MoneyDeposited => context.stop(self)
case RolledBack => context.stop(self)
}
}
}
Saga Pattern: Reactive Full Circle
• Garcia-Molina & Salem note:
• “search for natural divisions of the work being
performed”
• “it is the database itself that is naturally partitioned into
relatively independent components”
• “the database and the saga should be designed so that
data passed from one sub-transaction to the next via
local storage is minimized”
• fully aligned with Simple Components and isolation
34
Conclusion
Conclusion
• reactive systems are distributed
• this requires new (old) architecture patterns
• … helped by new (old) code patterns &
abstractions
• none of this is dead easy: thinking is
required!
36

More Related Content

PPT
Chapter 12 transactions and concurrency control
PDF
The Newest in Session Types
PPTX
Zookeeper Architecture
PPTX
Optimistic concurrency control in Distributed Systems
PPT
4. concurrency control
DOC
Database chapter 10 questions
PPTX
Database ,11 Concurrency Control
PDF
Conflict Resolution In Kai
Chapter 12 transactions and concurrency control
The Newest in Session Types
Zookeeper Architecture
Optimistic concurrency control in Distributed Systems
4. concurrency control
Database chapter 10 questions
Database ,11 Concurrency Control
Conflict Resolution In Kai

What's hot (7)

PPT
Clockless design language - ilia greenblat
PPT
Transactions
PPTX
Flink Architecture
PPTX
Cassandra Architecture
PPT
Advanced Hibernate
PPTX
Advanced Hibernate V2
PPT
Concurrency (Distributed computing)
Clockless design language - ilia greenblat
Transactions
Flink Architecture
Cassandra Architecture
Advanced Hibernate
Advanced Hibernate V2
Concurrency (Distributed computing)
Ad

Similar to Reactive Design Patterns by Dr.Roland Kuhn (20)

PDF
Reactive Design Patterns: a talk by Typesafe's Dr. Roland Kuhn
PDF
Reactive Design Patterns
PDF
Large volume data analysis on the Typesafe Reactive Platform - Big Data Scala...
PDF
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
PPTX
Serverless Stateful Architecture
PPTX
Designing distributed systems
PDF
Reactive reference architecture
PPTX
Chapter 05: Eclipse Vert.x - Service Discovery, Resilience and Stability Patt...
PPTX
Introduction to Microservices Patterns
PPTX
Introduction to Microservices Patterns
PDF
Reactor, Reactive streams and MicroServices
PPTX
Event Driven Microservices architecture
PPTX
Designing Fault Tolerant Microservices
PPTX
Akka Microservices Architecture And Design
PDF
Redis and Kafka - Advanced Microservices Design Patterns Simplified
PDF
Redis and Kafka - Simplifying Advanced Design Patterns within Microservices A...
PPTX
Building Reactive Applications With Akka And Java
PDF
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
PDF
Scalability, Availability & Stability Patterns
PPTX
Microservices with .Net - NDC Sydney, 2016
Reactive Design Patterns: a talk by Typesafe's Dr. Roland Kuhn
Reactive Design Patterns
Large volume data analysis on the Typesafe Reactive Platform - Big Data Scala...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
Serverless Stateful Architecture
Designing distributed systems
Reactive reference architecture
Chapter 05: Eclipse Vert.x - Service Discovery, Resilience and Stability Patt...
Introduction to Microservices Patterns
Introduction to Microservices Patterns
Reactor, Reactive streams and MicroServices
Event Driven Microservices architecture
Designing Fault Tolerant Microservices
Akka Microservices Architecture And Design
Redis and Kafka - Advanced Microservices Design Patterns Simplified
Redis and Kafka - Simplifying Advanced Design Patterns within Microservices A...
Building Reactive Applications With Akka And Java
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
Scalability, Availability & Stability Patterns
Microservices with .Net - NDC Sydney, 2016
Ad

More from J On The Beach (20)

PDF
Massively scalable ETL in real world applications: the hard way
PPTX
Big Data On Data You Don’t Have
PPTX
Acoustic Time Series in Industry 4.0: Improved Reliability and Cyber-Security...
PDF
Pushing it to the edge in IoT
PDF
Drinking from the firehose, with virtual streams and virtual actors
PDF
How do we deploy? From Punched cards to Immutable server pattern
PDF
Java, Turbocharged
PDF
When Cloud Native meets the Financial Sector
PDF
The big data Universe. Literally.
PDF
Streaming to a New Jakarta EE
PDF
The TIPPSS Imperative for IoT - Ensuring Trust, Identity, Privacy, Protection...
PDF
Pushing AI to the Client with WebAssembly and Blazor
PDF
Axon Server went RAFTing
PDF
The Six Pitfalls of building a Microservices Architecture (and how to avoid t...
PDF
Madaari : Ordering For The Monkeys
PDF
Servers are doomed to fail
PDF
Interaction Protocols: It's all about good manners
PDF
A race of two compilers: GraalVM JIT versus HotSpot JIT C2. Which one offers ...
PDF
Leadership at every level
PDF
Machine Learning: The Bare Math Behind Libraries
Massively scalable ETL in real world applications: the hard way
Big Data On Data You Don’t Have
Acoustic Time Series in Industry 4.0: Improved Reliability and Cyber-Security...
Pushing it to the edge in IoT
Drinking from the firehose, with virtual streams and virtual actors
How do we deploy? From Punched cards to Immutable server pattern
Java, Turbocharged
When Cloud Native meets the Financial Sector
The big data Universe. Literally.
Streaming to a New Jakarta EE
The TIPPSS Imperative for IoT - Ensuring Trust, Identity, Privacy, Protection...
Pushing AI to the Client with WebAssembly and Blazor
Axon Server went RAFTing
The Six Pitfalls of building a Microservices Architecture (and how to avoid t...
Madaari : Ordering For The Monkeys
Servers are doomed to fail
Interaction Protocols: It's all about good manners
A race of two compilers: GraalVM JIT versus HotSpot JIT C2. Which one offers ...
Leadership at every level
Machine Learning: The Bare Math Behind Libraries

Recently uploaded (20)

PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
Computer Software and OS of computer science of grade 11.pptx
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Transform Your Business with a Software ERP System
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Digital Strategies for Manufacturing Companies
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
top salesforce developer skills in 2025.pdf
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
history of c programming in notes for students .pptx
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
Introduction to Artificial Intelligence
Design an Analysis of Algorithms I-SECS-1021-03
Computer Software and OS of computer science of grade 11.pptx
CHAPTER 2 - PM Management and IT Context
Navsoft: AI-Powered Business Solutions & Custom Software Development
Transform Your Business with a Software ERP System
Understanding Forklifts - TECH EHS Solution
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Digital Strategies for Manufacturing Companies
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
top salesforce developer skills in 2025.pdf
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Wondershare Filmora 15 Crack With Activation Key [2025
history of c programming in notes for students .pptx
How to Choose the Right IT Partner for Your Business in Malaysia
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Introduction to Artificial Intelligence

Reactive Design Patterns by Dr.Roland Kuhn

  • 1. Reactive Design Patterns Dr. Roland Kuhn @rolandkuhn — CTO Actyx AG
  • 2. Reactive Design Patterns • currently in MEAP • all chapters done,
 in pre-production • use code 39kuhn (39% off),
 see http://rolandkuhn.com 2
  • 5. Resilience: Don’t put all eggs in one basket! 5
  • 6. Result: Responsiveness • elastic components that scale with their load • responses in the presence of partial failures 6
  • 7. Result: Decoupling • containment of • failures • implementation details • responsibility • shared-nothing architecture, clear boundaries 7
  • 8. Result: Maintainability & Fexibility • decoupled responsibility—decoupled teams • develop pieces at their own pace • continuous delivery • Microservices: Single Responsibility Principle 8
  • 9. Implementation: Message-Driven • focus on communication between components • model message flows and protocols • common transports: async HTTP, *MQ, Actors 9
  • 10. Reactive Traits 10 elastic resilient responsive maintainable extensible message-­‐driven Value Means Form
  • 12. Basically: Microservices Best Practices • Simple Component Pattern • DeMarco in «Structured analysis and system specification» (Yourdon, New York, 1979) • “maximize cohesion and minimize coupling” • Let-It-Crash Pattern • Candea & Fox: “Crash-Only Software” (USENIX HotOS IX, 2003) • Error Kernel Pattern • Erlang (late 1980’s) 12
  • 14. Request–Response Pattern 14 «Include a return address in the message in order to receive a response.»
  • 16. Request–Response Pattern • return address is often implicit: • HTTP response over same TCP connection • automatic sender reference capture in Akka • explicit return address is needed otherwise • *MQ • Akka Typed • correlation ID needed for long-lived participants 16
  • 17. Circuit Breaker Pattern 17 «Protect services by breaking the connection during failure periods.»
  • 18. Circuit Breaker Pattern • well-known, inspired by electrical engineering • first published by M. Nygard in «Release It!» • protects both ways: • allows client to avoid long failure timeouts • gives service some breathing room to recover 18
  • 19. Circuit Breaker Example 19 private object StorageFailed extends RuntimeException private def sendToStorage(job: Job): Future[StorageStatus] = { // make an asynchronous request to the storage subsystem val f: Future[StorageStatus] = ??? // map storage failures to Future failures to alert the breaker f.map { case StorageStatus.Failed => throw StorageFailed case other => other } } private val breaker = CircuitBreaker( system.scheduler, // used for scheduling timeouts 5, // number of failures in a row when it trips 300.millis, // timeout for each service call 30.seconds) // time before trying to close after tripping def persist(job: Job): Future[StorageStatus] = breaker .withCircuitBreaker(sendToStorage(job)) .recover { case StorageFailed => StorageStatus.Failed case _: TimeoutException => StorageStatus.Unknown case _: CircuitBreakerOpenException => StorageStatus.Failed }
  • 20. Multiple-Master Replication Patterns 20 «Keep multiple distributed copies,
 accept updates everywhere,
 disseminate updates among replicas.»
  • 21. Multiple-Master Replication Patterns • this is a tough problem with no perfect solution • requires a trade-off to be made between consistency and availability • consensus-based focuses on consistency • conflict-free focuses on availability • conflict resolution gives up a bit of both • each requires a different programming model and can express different transactional behavior 21
  • 22. Consensus-Based Replication • strong coupling between replicas to ensure that all are “on the same page” • unavailable during network outages or certain machine failures • programming model “just like a single thread” • Postgres, Zookeeper, etc. 22
  • 23. Replication with Conflict Resolution • requires conflict detection • resolution without user intervention will have to discard some updates • detection/resolution unavailable during partitions • programming model “like single thread” with caveat • popular RDBMS in default configuration offer this 23
  • 24. Conflict-Free Replication • express updates such that they can be merged • cannot express “non-local” constraints • all expressible updates can be performed under any conditions without losses or inconsistencies • replicas may temporarily be out of sync • different programming model, explicitly distributed • Riak 2.0, Akka Distributed Data 24
  • 25. Multiple-Master Replication Patterns • no one size fits all • you will have to think and decide! 25
  • 26. Saga Pattern 26 «Divide long-lived distributed transactions into quick local ones with compensating actions for recovery.»
  • 27. Saga Pattern: Background • Microservice Architecture means distribution of knowledge, no more central database instance • Pat Helland: • “Life Beyond Distributed Transactions”, CIDR 2007 • “Memories, Guesses, and Apologies”, MSDN blog 2007 • What about transactions that affect multiple microservices? 27
  • 28. Saga Pattern • Garcia-Molina & Salem: “SAGAS”, ACM, 1987 • Bank transfer avoiding lock of both accounts: • T₁: transfer money from X to local working account • T₂: transfer money from local working account to Y • C₁: compensate failure by transferring money back to X • Compensating transactions are executed during Saga rollback • concurrent Sagas can see intermediate state 28
  • 29. Saga Pattern • backward recovery:
 T₁ T₂ T₃ C₃ C₂ C₁ • forward recovery with save-points:
 T₁ (sp) T₂ (sp) T₃ (sp) T₄ • in practice Sagas need to be persistent to recover after hardware failures, meaning backward recovery will also use save-points 29
  • 30. Example: Bank Transfer 30 trait Account { def withdraw(amount: BigDecimal, id: Long): Future[Unit] def deposit(amount: BigDecimal, id: Long): Future[Unit] } case class Transfer(amount: BigDecimal, x: Account, y: Account) sealed trait Event case class TransferStarted(amount: BigDecimal, x: Account, y: Account) extends Event case object MoneyWithdrawn extends Event case object MoneyDeposited extends Event case object RolledBack extends Event
  • 31. Example: Bank Transfer 31 class TransferSaga(id: Long) extends PersistentActor { import context.dispatcher override val persistenceId: String = s"transaction-$id" override def receiveCommand: PartialFunction[Any, Unit] = { case Transfer(amount, x, y) => persist(TransferStarted(amount, x, y))(withdrawMoney) } def withdrawMoney(t: TransferStarted): Unit = { t.x.withdraw(t.amount, id).map(_ => MoneyWithdrawn).pipeTo(self) context.become(awaitMoneyWithdrawn(t.amount, t.x, t.y)) } def awaitMoneyWithdrawn(amount: BigDecimal, x: Account, y: Account): Receive = { case m @ MoneyWithdrawn => persist(m)(_ => depositMoney(amount, x, y)) } ... }
  • 32. Example: Bank Transfer 32 def depositMoney(amount: BigDecimal, x: Account, y: Account): Unit = { y.deposit(amount, id) map (_ => MoneyDeposited) pipeTo self context.become(awaitMoneyDeposited(amount, x)) } def awaitMoneyDeposited(amount: BigDecimal, x: Account): Receive = { case Status.Failure(ex) => x.deposit(amount, id) map (_ => RolledBack) pipeTo self context.become(awaitRollback) case MoneyDeposited => persist(MoneyDeposited)(_ => context.stop(self)) } def awaitRollback: Receive = { case RolledBack => persist(RolledBack)(_ => context.stop(self)) }
  • 33. Example: Bank Transfer 33 override def receiveRecover: PartialFunction[Any, Unit] = { var start: TransferStarted = null var last: Event = null { case t: TransferStarted => { start = t; last = t } case e: Event => last = e case RecoveryCompleted => last match { case null => // wait for initialization case t: TransferStarted => withdrawMoney(t) case MoneyWithdrawn => depositMoney(start.amount, start.x, start.y) case MoneyDeposited => context.stop(self) case RolledBack => context.stop(self) } } }
  • 34. Saga Pattern: Reactive Full Circle • Garcia-Molina & Salem note: • “search for natural divisions of the work being performed” • “it is the database itself that is naturally partitioned into relatively independent components” • “the database and the saga should be designed so that data passed from one sub-transaction to the next via local storage is minimized” • fully aligned with Simple Components and isolation 34
  • 36. Conclusion • reactive systems are distributed • this requires new (old) architecture patterns • … helped by new (old) code patterns & abstractions • none of this is dead easy: thinking is required! 36