Skip to main content

Leader/Followers

ConcurrencyPerformanceAbout 2 min

Intent

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.

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
Leader/Followers class diagram

Applicability

Use Leader-Followers pattern when

  • 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
  • JAWS
  • Real-time CORBA

Credits

  • Douglas C. Schmidt and Carlos O’Ryan - Leader/Followers