COMP2511
🧭 8.2 - Event-Driven & Asynchronous Design
Parallel/Async Paradigm
What is parallel/asynchronous programming?
-
Asynchronous programming, broadly speaking is any form of programming where processes are not necessarily sequentially executed
- Event loops (seen commonly in JavaScript, which is single-threaded)
-
Parallel programming: running multiple processes at the same time
- Parallelism (multi-threading)
- We will focus mainly on parallelism in this course
-
Parallelism vs Concurrency:
- Parallelism: The simultaneous execution of computations
- Concurrency: The art of managing parallelism
Parallel/Async Paradigm
Why program asynchronously or in parallel?
- Performance - sequential execution is too slow
- We don't want programs to become bottlenecked on blocking operations (e.g. reading a file, opening a web socket)
- Requirements to have real-time updates (e.g. instant messaging)
- Allows for better software design (we'll see soon)
Asynchronous Paradigm
In Week 7 we discussed concurrency, synchronisation and the Singleton Pattern - ways of managing the issues arise when programming in parallel.
Today, we'll discuss applications of asynchronous programming in software design.
The primary application is Event-Driven Programming and the Observer Pattern.
Promises
https://www.digitalocean.com/community/tutorials/understanding-the-event-loop-callbacks-promises-and-async-await-in-javascript
Event-Driven Revisited
- The Observer Pattern - way of propagating changes in state between software components
- Producers (AKA subjects) produce events
- Consumers (AKA subscribers, observers, listeners) consume events
- Producer/Consumer relationships can be 1:1, 1:M, M:1, M:M
- But first, some background
1. The Event-Driven Paradigm
- Event: A change in state
- In the event-driven paradigm, events are first class citizens
const element = document.getElementById("myBtn");
element.addEventListener("click", myFunction);
function myFunction(event) {
console.log(event.target.value)
}
2. State as a Series of Events
- We can think of the current state of a system to be the result of playing out all the events that have occurred
- Where have we seen this before?
- In the project?
- In your programming experience?
3. Streams Revisited
- Minimise coupling by letting data "flow down the stream"
List<Integer> ints =
strings2.stream()
.map(Integer::parseInt)
.collect(Collectors.toList());
Problems with the Synchronous Observer Pattern
- Problem 1 - What if while we are processing the first event, the second event comes along?
- Problem 2 - What if we start to increase the number of relationships:
- More producers
- More consumers
- More types of events
- Leads to high coupling
- The postman problem
Asynchronous Observer Pattern
- Instead of producers and consumers being directly coupled, they instead communicate over a shared channel
- Producers deposit events into the channel
- Events "flow through the channel"
- Consumers read from the shared channel and process the events
- Producers and consumers are all run in parallel
Asynchronous Observer Pattern
- What if a consumer's not interested?
- Can choose to consume certain types of events, and ignore others
- Good design
- Principle of Least Knowledge
- No coupling between producers and consumers
- Can add/remove producers or consumers at will
Implementation: Go Channels
- Go provides very good lightweight support for this design pattern with goroutines (you can think of them as lightweight threads) and channels (essentially a buffer)
- https://go.dev/play/p/MZo57Ei1NKW
- Need to consider blocking of goroutines on channels and problems of:
- Deadlock
- Starvation
Implementation: Apache Kafka
- Communication between repositories or APIs in a service ecosystem
Event Pipelines
- We can "play" events through a pipeline using this model
- What if we wanted to play back events?
- Process interrupted
- Data malformed
- Fix up and replay the events
- Need to design consumers for idempotency - what if they consume the same event twice?
- Need to determine if consumers rely on a particular ordering of events to be processed in
Final Thoughts
- It all just seems like glue?
- Trends of industry and modern software architecture
- Microservices and abstraction
- The need for event driven systems
- The role of design patterns in real-world software
COMP2511 23T2 - Event-Driven & Asynchronous Design, Part 2
By npatrikeos
COMP2511 23T2 - Event-Driven & Asynchronous Design, Part 2
- 1,556