COMP 310
Fall 2017

HW07: Remote task execution

Home  Info  Canvas   Java Resources  Eclipse Resources  Piazza

This project has a "compute engine" (ICompute) on the server  which is served out as a remote object.   The client then sends a "compute task" (ITask) to the server for it to execute, returning the result to the client.   The key issue here is that the server does not know a priori what the client will have it do

Before starting this assignment, be sure that you can run the demo from Lab08, which includes configuring your computer for use with RMI.

This assignment and all future assignments will use TCP ports in the ranges: 2001-2002 and 2099-2102.  Be sure they are all open on your computer!

This assignment page does NOT contain all the information necessary to successfully and properly complete the project! 
You MUST carefully read ALL THE DOCUMENTATION, including all Javadocs and README.txt's to fully understand the system and the project requirements.

 

References:

Obtaining the Provided Code

The code is available by setting the svn:externals property (under Team/Set Property) of your src folder to "provided https://svn.rice.edu/r/comp310/course/ComputeEngine/provided"

Be sure to set the working directory of both the client and server launch configurations to your the "bin" directory in your project.  
Also, set both the client and engine (server) launch configurations to be "shared" so that they will always be set correctly.
See the Eclipse Resources page for directions  

Ports that need to be opened (see the code for the values):

 

Click for full-size image
Compute Engine

Features

Read the code documentation!  (Be sure to read the package documentation too:  In the Javadoc web page, click the "Overview" tab and then click the package name in the right-side box.)

(Package Javadocs can also be found in the package-info.java file in the package.)

 

Demo JARs

The provided code includes fully operational demos for both the client and the engine server as executable JAR files in the provided.demo package.   See the Javadocs for that package for complete directions on how to run the demos and their capabilities.

It is an Honor Code violation to attempt to decompile the provided JAR files.

The demos are fully compliant with the required inter-computer API as defined by the provided.compute package.   Likewise, the provided sample tasks are API compliant.   The demo client, the demo engine and/or the provided sample tasks can thus all be used to test student solutions.    This will enable each piece of the project to be tested separately.   This is NOT, however, a substitute for the required testing with other students!  

Note: The demo client is only capable of loading ITask implementations that have a public static FACTORY field of type ITaskFactory.    The sample ITasks are pre-loaded into the demo client for convenience only (loaded by its controller -- not hardwired into the view or model!).

Use the demos as part of your development process:

One great advantage of having these fully operational demos at your disposal is that you can now completely separate the development of your client from your engine server from your custom tasks.  One of the goals of the project is to demonstrate how all these parts are completely decoupled, so that is exactly how you should structure your development process! 

 

Important concepts:

Be sure you are absolutely clear on exactly which objects in the system are

Misunderstanding which objects are which is the #1 stumbling block and the #1 source of errors in this project!

Stubs retrieved from remote Registries -- The ICompute stub that the client retrieves via the Registry delegates its calls back to its ComputeEngine implementation on the server.

Stubs sent and returned by stubs  (stubs as factories) -- IRemoteTaskViewAdapter stubs are both sent to the server via a method in the ICompute stub in the client as well as returned by the ICompute stub as a return value.  Thus a single stub can serve as a factory for all the other stubs that are needed, eliminating the need for multitudes of objects bound in the Registry--only a single factory needs to be bound.

Entire objects being serialized and sent via stubs -- the ITask objects are being completely serialized and sent over the network from the client to the server.  They are not sent as stubs.  

Automatic remote dynamic class loading of serialized objects -- If the server does not have the code for the concrete ITask sent to it, the RMI system settings that the client and server set up automatically cause the code for the task to be dynamically loaded from across the network, from the client's class server to the server.  Likewise, this is done for the stubs that are sent back and forth.

Task factories -- Abstractions of the task instantiation process that enable dynamic loading of tasks.  The provided ITaskFactory interface is designed to encapsulate the conversion of a String (as would be passed from a user interface) to whatever type of constructor parameter, i.e. not necessarily a String, the associated ITask implementation requires.  Typically, task factories do not require constructor parameters for their own instantiation, which helps further decouple the specific tasks from the rest of the system.    Student solutions are not required to use the provided ITaskFactory but justifications on the architecture used to enable dynamic task loading should be included in the documentation and/or README.txt file.

Task factory loaders -- An encapsulation of the process of dynamically loading a task factory.  While individual task factories are are generically typed to the return type of  the tasks they produce, i.e. ITaskFactory<T>,  task factory loaders' load() methods are typed to an unbounded wildcard return type, i.e. ITaskFactory<?>.   In terms of dynamic task loading, this enables the system architecture to be decoupled from the task return type.    The provided code includes an implementation of ITaskFactoryLoader that is able to load ITask implemenations that include a field, public static ITaskFactory FACTORY, that is the singleton task factory instance for that specific type of task.   Student solutions are not required to use the provided ITaskFactoryLoader but justifications on the architecture used to enable dynamic task loading should be included in the documentation and/or README.txt file.

Custom task result formatters -- The client application should be designed to be independent of the return type of the tasks that it loads and runs but the tasks need to keep the strong typing of their return types.  The ITaskResultFormatter interface provides a means for the client application to transparently convert the strongly-typed task results to useful and informative task-specific strings that can be displayed to the user.  Since the formatting of a result is specific to each instance of a task, the ITask interface provides a factory method for the task to generate its own custom formatter.   The client application only needs to deal with the formatters as a unbounded wildcard type:  ITaskResultFormatter<?>. or as a generic type, ITaskResultFormatter<T>, in a generic method (recommended, e.g. see IClientModel.runtTask()).    Theoretically, the compute engine could also use the task's result formatter, but on the engine side, one is generally more interested in the raw task results rather than a nicely formatted output.

Local vs. remote task view adapters -- There are two kinds of task view adapters in use by the system for two very different purposes:

 

Requirements:

You will need to create your OWN client and engine MVC implementations (two separate applications) plus your own custom ITask implementations.   Please see the IClientModel and IEngineModel interfaces for guidelines on building one's client and server implementations.  

You may NOT change any of the provided code -- you will receive a commit error if you do so!

Student work:

Students are required to design and implement both client and engine server applications plus custom tasks.

Note that the provided.compute package contains all the interfaces that BOTH the client and the server need to talk to each other.   Do NOT copy or modify this package!

Testing

Testing RMI programs can be tricky.   You can easily be fooled into thinking that your code runs properly if you test insufficiently.   In particular, if both ends of your test contain all the code, the remote dynamic class loading will not be tested.  Here's a more complete test:

Testing Requirements:

Most Common Errors

 

Grading Guidelines

  1. The at least 3 tasks implemented that must return at least 3 different types of results.   - 15 pts
  2. All tasks are dynamically loaded into the client.  No tasks are hardwired into the client or engine applications. - 5 pts
  3. Able to dynamically create,  send and execute a composite task.   - 3 pts
  4. The tasks' results should be displayed on the client and engine's views, with task-specific formatting, using the task's ITaskResultFormatter object, appearing on the client.   - 5 pts
  5. The task execution must display some sort of status message on the server when it is run.   That is, the task's execute method should utilize the ILocalTaskViewAdapter given to it by the compute engine to display a status message. - 5 pts
  6. An IRemoteTaskViewAdapter stub properly created on the client and automatically transmitted to the server upon connection. - 5 pts
  7. An IRemoteTaskViewAdapter stub properly created on the engine server and automatically transmitted to the client upon connection. - 5 pts
  8. Connection status messages sent both ways between the client and server automatically upon connection. - 5 pts
  9. Able to send string message from client's view to connected compute engine's view. - 5 pts
  10. Able to send string message from compute engine's view to connected client's view.- 5 pts
  11. The task should run properly when both the client and server are on the same machine.   This implies the ability to connect. - 5 pts
  12. The task should run properly when the client and server are on different machines.  This implies the ability to connect. Test this between your and your partner's machines! Your code will be tested against a course staff machine. - 5 pts
  13. The above described testing requirements were met.  - 15 pts
  14. Run configurations created and saved in repository for both client and compute engine. - 5 pts
  15. Full Javadocs and UML diagrams covering the both client and engine server applications.  - 5 pts
  16. Discretionary - 7 pts

Note that the above requirements mean that you cannot change anything in the provided.compute or provided.rmiUtils packages!


© 2017 by Stephen Wong