docs: Finished Explanation for Leader/Followers #2239 (#2733)

* Added documentation for Feature Toggle design pattern

* Explanation for Feature Toggle Issue #2230 finished, added intent, explanation, programmatic example, applicability and consequences

* Finished Explanation for Leader/Followers #2239
This commit is contained in:
JackH408
2024-03-17 18:45:13 +11:00
committed by GitHub
parent dc9ee19445
commit c7c0828a07
+84 -9
View File
@@ -3,28 +3,103 @@ title: Leader/Followers
category: Concurrency
language: en
tag:
- Performance
- Performance
---
## Intent
The Leader/Followers pattern provides a concurrency model where multiple
threads can efficiently de-multiplex events and dispatch event handlers
that process I/O handles shared by the threads.
The Leader/Followers design pattern is a pattern used to coordinate a selection of 'workers'. It allows tasks to execute concurrently
with the Leader delegating tasks to the Follower threads for execution. It is a very common design pattern used in multithreaded
situations such as servers, and works to help prevent ambiguity around delegation of tasks.
## Explanation
Real-world Example
> The best real world example of Leader/Followers is a web server. Web servers have to be able to handle a multitude of incoming
> connections all at once. In a web server, the Leader/Followers pattern works by using the Leader to listen to incoming requests
> and accept connections. Once a connection is made to a client the Leader can then find a Follower thread to delegate the task
> to for execution and return to the client. This means that the Leader does not have to wait to finish execution before it can
> accept another incoming connection, and can focus on delegating tasks. This pattern is created to aid in concurrency of applicaitons,
> allowing for many connections to work simultaneously.
In plain words
> You can picture the Leader as a traffic controller that has to direct traffic from one lane into 25 lanes. As a car comes in,
> the Leader sends it down a road that isn't full or busy. This car can then have its request filled, or reach its destination.
> If the Leader had to drive each car down the lane itself, the line would pile up and progress would be slow. But as the Leader
> has Followers that can also drive the cars, the Leader can focus on making the line move quickly and ensuring traffic doesn't
> back up.
Wikipedia says
> A concurrency pattern are those types of design patterns that deal with the multi-threaded programming paradigm.
## Programmatic Example
This example shows Java code that sets up a Leader that listens for client requests on port 8080. Once a request is sent,
the leader will accept it and delegate it to a new Follower to execute. This means that the Leader can keep delegating,
and ensure requests are fulfilled timely. This is only pseudocode and the working code would require a more concrete implementation
of Leader and Followers.
```java
public class LeaderFollowerWebServer {
public static void main(String[] args) throws IOException {
int port = 8080; // the port that clients can reach the leader on
int numFollowers = 5; // the amount of followers we can delegate tasks to
ServerSocket serverSocket = new ServerSocket(port); // pseudocode for creating a socket to the server
ExecutorService executorService = Executors.newFixedThreadPool(numFollowers); // pseudocode to start execution for Followers
System.out.println("Web server started. Listening on port " + port);
while (true) {
Socket clientSocket = serverSocket.accept();
// Accept a new connection and assign it to a follower thread for processing
executorService.execute(new Follower(clientSocket));
}
}
}
class Follower implements Runnable {
private final Socket clientSocket;
public Follower(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
// handle the client request, e.g., read and write data
// this is where you would implement your request processing logic.
// we will just close the socket
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
## Class diagram
![Leader/Followers class diagram](./etc/leader-followers.png)
## Applicability
Use Leader-Followers pattern when
* multiple threads take turns sharing a set of event sources in order to detect, de-multiplex, dispatch and process service requests that occur on the event sources.
* You want to establish a concurrent application
* You want faster response times on heavy load
* You want an easily scalable program
* You want to load balance a program
## Consequences
Consequences involved with using the Leader/Followers pattern
* Implementing this pattern will increase complexity of the code
* If the leader is too slow at delegating processes, some Followers may not get to execute tasks leading to a waste of resources
* There is overhead with organising and maintaining a thread pool
* Debugging is more complex
## Real world examples
* [ACE Thread Pool Reactor framework](https://www.dre.vanderbilt.edu/~schmidt/PDF/HPL.pdf)
* [JAWS](http://www.dre.vanderbilt.edu/~schmidt/PDF/PDCP.pdf)
* [Real-time CORBA](http://www.dre.vanderbilt.edu/~schmidt/PDF/RTS.pdf)
* ACE Thread Pool Reactor framework
* JAWS
* Real-time CORBA
## Credits
* [Douglas C. Schmidt and Carlos ORyan - Leader/Followers](http://www.kircher-schwanninger.de/michael/publications/lf.pdf)
* Douglas C. Schmidt and Carlos ORyan - Leader/Followers