Distributed programming to calculate the fibonacci sequence. The Fibonacci numbers, commonly denoted Fn , form a sequence, the Fibonacci sequence, in which each number is the sum of the two preceding.
We're going to use a project with two sub-projects to build the Client and Server applications. The requirements for our sub-projects are the same so we'll do all the setup in the subprojects block of the root project, which applies to all sub-projects. Edit the generated build.gradle file to look like the one below:
...
"Class-Path": configurations.runtimeClasspath.resolve().collect { it.toURI() }.join(' ')
...
In order for it to be independent of the computer on which it is developed, it should look like this:
...
"Class-Path": 'opt/Ice-3.7.6/lib/ice-3.7.6.jar'...
We must also edit the generated settings.gradle to define our sub-projects:
rootProject.name = 'ice'
include 'client'
include 'server'
Besides that, we must edit the file config.server located in server/src/main/resources with the host and port where the server will be deployed, the default server values are these:
Printer.Endpoints=tcp -p 9099
Ice.Default.Host=localhost
Finally, we must edit the file config.client located in client/src/main/resources with the values of the server we want to communicate, the default client values are these:
Printer.Proxy=SimplePrinter:tcp -p 9099
Callback.Client.Endpoints=default -h localhost
Ice.Default.Host=localhost
As an observation, if you want to run our product remotely, you must change the resource file that is inside the jar (zip) and you must modify the host by the ip and port where the logical interface of your computer is located. We will place an example of how we do it using zerotier as a logical interface identifying the server on the xhgrid9 pc.
- For your local pc
Ice.Default.Host=10.147.19.125
- For remotes pc
Ice.Default.Host=192.168.131.49 # hgrid9.icesi.edu.co (DNS resolves ip)
- In your local pc
Callback.Client.Endpoints=default -h 10.147.19.218 # Your ip in zerotier logic interface
Ice.Default.Host=10.147.19.125 # xhgrid9 (DNS resolves ip)
- In remote pc
Callback.Client.Endpoints=default -h 192.168.131.51 # Or hotsname specific of the remote client (hgrid11.icesi.edu.co)
Ice.Default.Host=hgrid9
Sending jar files using scp command:
scp server.jar swarch@xhgrid9:.
scp client.jar swarch@xhgrid10:.
scp client.jar swarch@xhgrid11:.
gradle build
java -jar server/build/libs/server.jar
java -jar client/build/libs/client.jar
- To run client and server, we first start the server in a separate window:
- At this point, we wont see anything because the server simply waits for a client to connect to it. We run the client in a different window:
Some examples of the client and server communication are documentated below:
To get rid of the server, we interrupt it on the command line for now. And, to get rid of the client you must write exit.
The implementation of part I will be in the callback-part-I branch, to go to this branch do clcik hear
To see the analysis and the conclusion reached after automating the process go to the following link
Important remark: In order to run the bash scripts, you must have the bash package installed. sshpass. If you are on a Linux operating system, run:
sudo apt-get install sshpass
If the execution environment is Windows, you must execute the .sh through the Cygwin terminal with the sshpass package installed or from a WSL execution environment with the sshpass package installed.
- To build our project, we must execute the following command:
gradle build
- Once the project is built, our project will already have the .Jar files ready to run the clients and the server on remote pc's. The first thing we must do is to execute the script that will send the .Jar files to the corresponding machines. For this, we must execute the following command:
./deploy.sh $1
Where "$1" is a string containing the ids of the machines to which the .Jar will be sent (Clients). To send the script to several machines we must separate the ids by commas. For example, if we want to send the script to machines 4,5,6 and 7, we must execute the following command:
./deploy.sh 4,5,6,7
The .Jar from the server will always be sent to machine 2.
- Run the server on machine 2. To do this, we must execute the following series of commands, from connecting remotely to machine 2, to running the server's .Jar:
ssh swarch@xhgrid2
cd GabrielSuarez-AlejandroVarela-CallBack
./deployServer.sh
- To run the clients, the deployServer script must be running so the Server too. Server must be running. Once this is done, we can move on to running the clients. To run the clients, the following command must be executed:
./deployClient.sh $1 $2
Where $1 must be equal to the value that was passed in the deploy.sh and $2 must be equal to the numbers with which you want to perform the fibonacci, like the clients, can be more than one number separated by commas, for example, if you want to run the fibonacci of the number 10 you must run the following command taking into account the clients mentioned above:
./deployClient 4,5,6,7 10
- With this we will already have automated the execution of our system, to see the results of the server after the execution, you must go to the machine 2 and execute the following command:
ssh swarch@xhgrid2
cd GabrielSuarez-AlejandroVarela-CallBack
cat server.log
Now to see the result of the clients, we will only look at the client.log file that will be stored at the same level of the deploy .sh.
- Multi-threaded so that it can respond to multiple requests from different clients, concurrently. Is this concurrency virtual or is it real? how can you prove it? Attach a screenshot of the test.
The server uses real concurrency techniques, such as multithreading, to handle incoming requests. It also uses task planning techniques to allocate resources fairly and equitably to each request. The server will also implement concurrency control techniques, such as semaphores, to avoid race conditions and ensure the integrity of shared data.
- Answer, with this new version, the two points of Part I.
We can see that the print comes out through the server's standard output, which means that for numbers of the order of 10 ^8 the print takes longer than what the calculation indicates. Due to main thread blocking our program main thread is busy printing.
We test up to 10 * 10^8 and get a result or timeout of 9 seconds in that order of ideas for. reach the ice time out of 60 seconds knowing that the time complexity of this algorithm is exponential, the approximate number is 6.6 * 10 ^8.
- To allow a client to "register", with the hostname and what is necessary for them to make a callback.
if (!this.clients.containsKey(hostname)) {
this.clients.put(hostname, client);
System.out.println(hostname + " joined. \n"); // Debug Porpouses
}
- Regarding the messages, if the received message: a. Starts with "list clients", it should return the list of clients (hostnames or their prefix) registered on the server. b. Starts with "to X:", it should send the remainder of the message to X, where X is the destination hostname (or its prefix). c. Starts with "BC" (broadcast), the message must be returned by the server to ALL clients registered with it.
if (message.startsWith("exit")) {
this.handler.removeClient(host);
} else if (message.startsWith("list clients")) { // list clients
replyHosts(getHosts());
} else if (message.startsWith("bc")) { // bc message
emitBroadcast(host, message);
} else if (message.startsWith("to")) { // to host:message
String to = message.replace("to", "").trim().split(":", 2)[0];
String msg = message.replace("to", "").trim().split(":", 2)[1];
send(host, to, msg);
} else { // Fibonacci Calculation
this.proxy.callback(validationLayer(this.message));
}
- This problem was resolve implementing a CallBack, this CallBack has a real concurrency, to see more information about this.
To see the analysis and the conclusion reached after automating the process go to the following link