Alan Kaminsky Department of Computer Science Rochester Institute of Technology 4486 + 2220 = 6706
Home Page
[an error occurred while processing this directive]

4005-730 Distributed Systems
Grid Computing System Version 3

Prof. Alan Kaminsky
Rochester Institute of Technology -- Department of Computer Science
Adapted by Prof. Warren R. Carithers, 2011/01/03

Overview
The Grid Computing System
Software Requirements
Example Command Lines


Overview

Write a Java program for a simulated grid computing system. The program will include distributed processes for the various entities in the grid computing system, as well as a user client. The distributed processes will communicate with each other using tuple space. This version will assume there is only one client running at a time and that processes never fail.


The Grid Computing System

The Grid Computing System (GCS) provides CPU cycles as a public utility, like electricity. The GCS has a number of compute servers. 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 tells 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 servers 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 also tells each compute server in the list what the next compute server is (except the last compute server has no successor). When the client tells the first compute server to perform the calculation on a given number, the first compute server tells the second compute server, the second compute server tells 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.

When a particular compute server is available, the following tuple exists in tuple space:

When each compute server starts up, it writes this tuple into tuple space.

When a particular compute server is reserved for a calculation session, the following tuple exists in tuple space:

To reserve a compute server, the client takes the server available tuple and writes the server reserved tuple. To unreserve a compute server, the client takes the server reserved tuple and writes the server available tuple. Each compute server reads the server reserved tuple to find out which function to compute and which successor to use.

When a particular compute server is to calculate its function value for a given argument, the following tuple exists in tuple space:

The second tuple slot contains the name of the compute server that is supposed to calculate its function value. The third tuple slot contains a serial number that links the argument tuple to the corresponding result tuple. Serial numbers start at 1 and increase. For each function argument to be calculated, the fourth tuple slot contains the argument value and the fifth tuple slot contains the value false. When there are no more function arguments, the fourth tuple slot contains the value 0 (which is ignored) and the fifth tuple slot contains the value true.

When a particular compute server has calculated its function value for a given argument, the following tuple exists in tuple space:

The second tuple slot contains the name of the compute server that calculated its function value. The third tuple slot contains a serial number that links the result tuple to the corresponding argument tuple.

In order to slow the system down so we humans can watch its operation, each compute server method adds a two-second delay after reading a function argument tuple and before writing the function result tuple.


Software Requirements

    Function Interface
     
  1. The system must have an interface representing a function to be calculated.
     
  2. The function interface must have a method that returns the name of the function, a String.
     
  3. The function interface must have a method for calculating the function.
     
    1. The method must have an argument, which is a double precision floating point number.
       
    2. The method must return the result of applying the function to the argument, which is a double precision floating point number.
       
  4. The function interface must be written as follows, and it must not be in a package:
        public interface Function
            {
            public String name();
            public double f (double x);
            }
    
    Compute Server
     
  5. The system must have a process for each compute server.
     
  6. An instance of the compute server must be run by typing this command line:
    java ComputeServer <host> <port> <ts> <name>
    

    Note: This means that the compute server object's class must be named ComputeServer, and this class must not be in a package.
     
  7. A compute server object's constructor must throw an exception if there are any of the following problems with the command line arguments. The exception's detail message must be a meaningful explanation of the problem.
  8. The compute server object must behave as specified above under "The Grid Computing System."
     
  9. A compute server object must display its state at all times; specifically:
     
    1. Immediately after the compute server is created, and whenever the compute server leaves a calculation session, the compute server must print the following line on the console:
      Compute Server <name> -- available
      
      where <name> is replaced with the name of the compute server.
       
    2. Whenever the compute server enters a calculation session, the compute server must print the following lines on the console:
      Compute Server <name> -- reserved
      Compute Server <name> -- function: <func>
      Compute Server <name> -- successor: <succ>
      
      where <name> is replaced with the name of the compute server, <func> is replaced with the name of the function, and <succ> is replaced with the name of the compute server's successor; if there is no successor, the third line is omitted.
       
    3. Whenever the compute server starts to perform a calculation, before performing the actual calculation, the compute server must print the following line on the console:
      Compute Server <name> -- f(<arg>)
      
      where <name> is replaced with the name of the compute server and <arg> is replaced number upon which to perform the calculation.
       
    4. Whenever the compute server finishes performing a calculation and is about to return the calculated function value, the compute server must print the following line on the console:
      Compute Server <name> -- <func>(<arg>) = <val>
      
      where <name> is replaced with the name of the compute server, <func> is replaced with the name of the function the compute server is calculating, <arg> is replaced with the function's argument value, and <val> is replaced with the function's return value.
       
  10. After performing a calculation, the compute server must add a two-second delay before reporting the calculation's result.
     
  11. The compute server must not print anything other than what is specified above.
     
    Client Program
     
  12. The system must have a compute client main program to perform calculations on a series of numbers.
     
  13. The compute client program must be run by typing this command line:
     
    java ComputeClient <host> <port> <ts> <func> <name> [ <func> <name> ... ]
     
    Note: This means that the compute client program's class must be named ComputeClient, and this class must not be in a package.
     
  14. The compute client program must print an error message and terminate without starting a computation session if there are any of the following problems with the command line arguments. The error message must include a meaningful explanation of the problem. The error message may include an exception stack trace.
  15. The compute client program must behave as specified above under "The Grid Computing System."
     
  16. The compute client program must read from the standard input zero or more numbers upon which to perform the calculations.
     
  17. Each line of the compute client program's standard input must consist of one double precision floating point number.
     
  18. If the compute client program cannot parse a line of the standard input as a double precision floating point number, the compute client program must shut down the computation session, print an error message, and terminate. The error message must include a meaningful explanation of the problem. The error message may include an exception stack trace.
     
  19. After obtaining the result of the calculation on each number read from the standard input, the compute client program must print the following line on the console:
    f(<arg>) = <val>
    
    where <arg> is replaced with the number read from the standard input and <val> is replaced with the result of the calculation.
     
  20. If an exception occurs and the above requirements do not state how to handle the exception, the compute client program must shut down the computation session if necessary, print an error message, and terminate. The error message must include a meaningful explanation of the problem. The error message may include an exception stack trace.
     
  21. The compute client program must not print anything other than what is specified above.


Server Source Code


Client Source Code


Example Command Lines

To perform an example calculation session, run the following commands, each in a separate process on the same machine.

  1. Run the Registry Server and tuple space (script: runregistry).

    $ runregistry

    #!/bin/bash
    java \
    -classpath /home/fac/ark/public_html/cscl.jar \
    Start edu.rit.ds.registry.RegistryServer + \
    edu.rit.ds.space.SimpleSpace TS

  2. Set up a security policy for the Compute Server (policy file: policy).

    grant codebase "file:/home/fac/wrc/www/courses/common/ds/gcs/gcs03/"
        {
        permission java.security.AllPermission;
        };
    grant codebase "file:/home/fac/ark/public_html/cscl.jar"
        {
        permission java.security.AllPermission;
        };

  3. Run several instances of the Compute Server, specifying the security policy (script: runcomputeserver).

    $ runcomputeserver A
    $ runcomputeserver B
    $ runcomputeserver C

    #!/bin/bash
    java \
    -classpath /home/fac/wrc/www/courses/common/ds/gcs/gcs03:/home/fac/ark/public_html/cscl.jar \
    -Djava.security.policy=policy \
    ComputeServer localhost 9901 TS $1

  4. Set up a security policy for the Compute Client (policy file: client/policy).

    grant codebase "file:/home/fac/wrc/www/courses/common/ds/gcs/gcs03/client/"
        {
        permission java.security.AllPermission;
        };
    grant codebase "file:/home/fac/ark/public_html/cscl.jar"
        {
        permission java.security.AllPermission;
        };

  5. Set up a web server so that class files in the client's class path can be downloaded from a URL. This is called the codebase URL.
     
  6. Run the Compute Client, specifying the security policy and the client's codebase URL (script: client/runclient). Specify function class names and compute server names on the command line. Type arguments upon which to calculate the function. Hit CTRL-D (end-of-file) when done.

    $ 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/gcs03/client:/home/fac/wrc/www/courses/common/ds/gcs/gcs03:/home/fac/ark/public_html/cscl/lib \
    -Djava.security.policy=policy \
    -Djava.rmi.server.codebase=http://www.cs.rit.edu/~wrc/courses/common/ds/gcs/gcs03/client/ \
    ComputeClient localhost 9901 TS $*
    

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]
Alan Kaminsky Department of Computer Science Rochester Institute of Technology 4486 + 2220 = 6706
Home Page
Copyright © 2007 Alan Kaminsky. All rights reserved. Last updated 13-Jan-2007. Please send comments to ark­@­cs.rit.edu. Adaptations last updated 2011/01/03 by Warren R. Carithers.