| Home Page |
Overview
The Grid Computing System
Software Requirements
Example Command Lines
Write a Java program for a simulated grid computing system. The program will include distributed objects for the various entities in the grid computing system, as well as a user client. The distributed objects will reside in multiple processes running on different host computers, and communicating with each other using Java remote method invocation (RMI). This version will assume there is only one client running at a time and that processes never fail.
The Grid Computing System (GCS) provides CPU cycles as a public utility, like electricity. The GCS has a number of compute server objects. Each compute server does just one thing: it calculates a mathematical function of a double precision floating point number and returns the result.
A client can reserve a compute server in order to perform a computation on a series of numbers. After it reserves the compute server, the client specifies which mathematical function the compute server is to calculate. To do so, the client provides the server with a function object that implements interface Function:
public interface Function
{
public String name();
public double f (double x);
}
The client then calls a method on the compute server
to perform the calculation on a given number.
The compute server calls the function object's f() method
on that number and returns the result to the client.
The client repeats this for as many numbers as desired.
Then the client releases the compute server,
making the compute server available for other clients to use.
For example, if the client wants the compute server to calculate the sine of each number, the client provides the compute server with a function object that is an instance of this class:
public class SineFunction
implements Function
{
public String name()
{
return "sin";
}
public double f (double x)
{
return Math.sin (x);
}
}
The GCS also lets a client compose several functions together. For example, suppose the client wants to compute three functions, a, b, and c, on each number x to produce the result y = a(b(c(x))). The client sets up a list of function objects, one for each individual function. The client also sets up a list of compute server objects that will be used to calculate each individual function. The client reserves each compute server in the list and specifies each compute server's function object as before. The client then goes back and tells each compute server in the list what the next compute server is (except the last compute server has no successor). When the client calls a method on the first compute server to perform the calculation on a given number, the first compute server calls the second compute server, the second compute server calls the third compute server, and so on until the last compute server is reached. Then each compute server performs its calculation and returns the result to the previous compute server; the first compute server returns the ultimate result to the client. The client repeats this for as many numbers as desired. Then the client releases each of the compute servers, making the compute servers available for other clients to use.
Here is an example of a client using the GCS to calculate the square of the natural logarithm of the sine of a series of numbers: y = sqr(log(sin(x))). The compute server objects are named A, B, and C.
Client Compute Server A Compute Server B Compute Server C
| | | |
|reserve() | | |
|----------------------------->| | |
| return| | |
|<-----------------------------| | |
|reserve() | | |
|------------------------------------------------------------>| |
| | return| |
|<------------------------------------------------------------| |
|reserve() | | |
|------------------------------------------------------------------------------------------->|
| | | return|
|<-------------------------------------------------------------------------------------------|
|setFunction(sqr) | | |
|----------------------------->| | |
| return| | |
|<-----------------------------| | |
|setFunction(log) | | |
|------------------------------------------------------------>| |
| | return| |
|<------------------------------------------------------------| |
|setFunction(sin) | | |
|------------------------------------------------------------------------------------------->|
| | | return|
|<-------------------------------------------------------------------------------------------|
|setSuccessor(B) | | |
|----------------------------->| | |
| return| | |
|<-----------------------------| | |
|setSuccessor(C) | | |
|------------------------------------------------------------>| |
| | return| |
|<------------------------------------------------------------| |
| | | |
|apply(0.5) | | |
|----------------------------->| | |
| |apply(0.5) | |
| |----------------------------->| |
| | |apply(0.5) |
| | |----------------------------->|
| | | return 0.479| sin(0.5) = 0.479
| | |<-----------------------------|
| | return -0.735| | log(0.479) = -0.735
| |<-----------------------------| |
| return 0.540| | | sqr(-0.735) = 0.540
|<-----------------------------| | |
| | | |
|apply(1.0) | | |
|----------------------------->| | |
| |apply(1.0) | |
| |----------------------------->| |
| | |apply(1.0) |
| | |----------------------------->|
| | | return 0.841| sin(1.0) = 0.841
| | |<-----------------------------|
| | return -0.173| | log(0.841) = -0.173
| |<-----------------------------| |
| return 0.030| | | sqr(-0.173) = 0.030
|<-----------------------------| | |
| | | |
|release() | | |
|----------------------------->| | |
| return| | |
|<-----------------------------| | |
|release() | | |
|------------------------------------------------------------>| |
| | return| |
|<------------------------------------------------------------| |
|release() | | |
|------------------------------------------------------------------------------------------->|
| | | return|
|<-------------------------------------------------------------------------------------------|
| | | |
In order to slow the system down so we humans can watch its operation, each compute server method adds a two-second delay before returning.
public interface Function
{
public String name();
public double f (double x);
}
Compute Server Object
To perform the example calculation session depicted in the above timeline under "The Grid Computing System," run the following commands, each in a separate process on the same machine.
$ runregistry
#!/bin/bash java \ -classpath /home/fac/ark/public_html/cscl/lib \ Start edu.rit.ds.registry.RegistryServer |
grant codebase "file:/home/fac/wrc/www/courses/common/ds/gcs/gcs01/"
{
permission java.security.AllPermission;
};
grant codebase "file:/home/fac/ark/public_html/cscl/lib/"
{
permission java.security.AllPermission;
};
|
$ runcomputeserver A $ runcomputeserver B $ runcomputeserver C
#!/bin/bash java \ -classpath /home/fac/wrc/www/courses/common/ds/gcs/gcs01:/home/fac/ark/public_html/cscl/lib \ -Djava.security.policy=policy \ Start ComputeServer localhost 9901 $1 |
grant codebase "file:/home/fac/wrc/www/courses/common/ds/gcs/gcs01/client/"
{
permission java.security.AllPermission;
};
grant codebase "file:/home/fac/ark/public_html/cscl/lib/"
{
permission java.security.AllPermission;
};
|
$ runclient SqrFunction A LogFunction B SineFunction C 0.5 1.0 CTRL-D
#!/bin/bash java \ -classpath /home/fac/wrc/www/courses/common/ds/gcs/gcs01/client:/home/fac/wrc/www/gcs/gcs01:/home/fac/ark/public_html/cscl/lib \ -Djava.security.policy=policy \ -Djava.rmi.server.codebase=http://www.cs.rit.edu/~wrc/gcs/gcs01/client/ \ ComputeClient localhost 9901 $* |
Compute Server A prints the following on the console (the floating point numbers may print with additional digits of precision):
Compute Server A -- available Compute Server A -- reserved Compute Server A -- function: sqr Compute Server A -- successor: B Compute Server A -- f(0.5) Compute Server A -- sqr(-0.735) = 0.540 Compute Server A -- f(1.0) Compute Server A -- sqr(-0.173) = 0.030 Compute Server A -- available
Compute Server B prints the following on the console (the floating point numbers may print with additional digits of precision):
Compute Server B -- available Compute Server B -- reserved Compute Server B -- function: log Compute Server B -- successor: C Compute Server B -- f(0.5) Compute Server B -- log(0.479) = -0.735 Compute Server B -- f(1.0) Compute Server B -- log(0.841) = -0.173 Compute Server B -- available
Compute Server C prints the following on the console (the floating point numbers may print with additional digits of precision):
Compute Server C -- available Compute Server C -- reserved Compute Server C -- function: sin Compute Server C -- f(0.5) Compute Server C -- sin (0.5) = 0.479 Compute Server C -- f(1.0) Compute Server C -- sin (1.0) = 0.841 Compute Server C -- available
The compute client program prints the following on the console (the floating point numbers may print with additional digits of precision):
f(0.5) = 0.540 f(1.0) = 0.030
[an error occurred while processing this directive]
| Home Page |