You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 6, 2023. It is now read-only.
This is a Spring boot v3.0 repository which attempts to solve Problem 3 as defined in the Pesapal Careers portal.
How to Install and Run the Project
Clone this repository
Ensure you have Java 17 installed on your machine.
Start your preferred Java supporting IDE e.g. Intellij.
Open this project with the IDE and allow it to load and prepare the project to build with Gradle.
Finally run the Gradle bootRun command.
You can use Postman or cURL to test the end points.
Problem 3: A distributed system.
Build a TCP server that can accept and hold a maximum of N clients (where N is configurable).
These clients are assigned ranks based on first-come-first-serve, i.e whoever connects first receives the next available high rank. Ranks are from 0–N, 0 being the highest rank.
Clients can send to the server commands that the server distributes among the clients. Only a client with a lower rank can execute a command of a higher rank client. Higher rank clients cannot execute commands by lower rank clients, so these commands are rejected. The command execution can be as simple as the client printing to console that command has been executed.
If a client disconnects the server should re-adjust the ranks and promote any client that needs to be promoted not to leave any gaps in the ranks.
Solution
The following describes how i tackled the above problem. Let's start with the Endpoints then code, where i will show you how each of the endpoint functions was built.
The following are the resources available from the base url:
Providing a client to the server
For the server to accept the client, provide the client's name with the request /solution/register as a POST request and add json body similar to the one shown below.
On success you will get a response with CREATED http status to mean that it was a success otherwise you will get an exception with reason.
However when you try to add an already existing client you will receive a Bad Request error as shown below.
List clients on the server
To fetch list of active clients use /solution/clients as a GET request and with a json body as shown below.
curl --location --request GET 'http://localhost:8080/pesa-pal/problem3/api/v1/solution/clients'
On success you will get a response with OK http status and json array body with the to mean that it was a success otherwise you will get an exception with reason.
Ping Server
The client is required to ping the server after every 60 seconds with /solution/online as a POST request and with a json body as shown below.
On success you will get a response with HTTP Status 200 to mean that it was a success otherwise you will get an exception with reason.
The following are some of the exceptions that can be thrown:
Code
Project directory structure:
To effectively solve the larger part of the problem, I choose to use the Queue<?> datatype becuse of its elastic ability on the items it holds. Therefore items in the Queue automatically adjusts to the FIFO order.
The following are code snipnnets for important functions in the application:
if ((clientRank - (CLIENT_QUEUE.size() - 1)) < 0) {
IntStream.range(0, CLIENT_QUEUE.size())
.filter(rank -> rank > clientRank)
.forEach(rank -> log.info("Client '{}'\t|\tExecuting the command '{}' on behalf of the superior client '{}'.", CLIENT_QUEUE.stream().toList().get(rank), command, client));
returntrue;
} else {
returnfalse;
}
}
/**
* This function updates the list of online clients who have been inactive for over 60 seconds
*
* @return The runnable thread with instructions to remove clients.