In the first project, you implemented a naming service that used a mutlicast discovery protocol. This protocol was passive in nature, that is no discovery happens until it is requested. Several naming services could be within range of communication, all binding and unbinding objects locally but none would ever learn about objects available at one of the other naming services unless they made a request. We will change this to active system in which some announcement is made whenever objects are bound or unbound. This is the first part of the second project. The next portion will make specific use of changes we are making in this active discovery system.
*
These are very small commands, and should be very easy to insert into the naming service
you designed in Project 1.
To implement an active discovery system, we need to add two simple announcement commands. NAMING-ANNOUNCE and NAMING-UNANNOUNCE. These commands are issued by a naming service as soon as an object is bound or unbound. They are not sent as a response to another packet like the NAMING-REQUEST packet. These commands will make it possible to keep a mapping of remotely bound objects up to date automatically, this mapping is described in detail after the commands are introduced.
NAMING-ANNOUNCE contains the same information as a NAMING-RESPONSE, so it is followed by a signature, service name, host, port and key. NAMING-UNANNOUNCE is followed only by a signature and the name of service that has been unbound and is no longer available. for example,
"NAMING-ANNOUNCE,signature,SpecificService,pollux,9999,XQEWRS" "NAMING-UNANNOUNCE,signature,SpecificService"In addition to the two new commands, the wildcard request ("*") will be modifed slightly. Currenty, the wildcard in a NAMING-REQUEST prompts a naming service to send a series of responses - listing all known services. The change you will be make should allow a wildcard to be used with a prefix (very much like the DOS prompt treats wilds cards)
"NAMING-REQUEST,signature,*,pollux,9999,XQEWRS"For example, to request a list of all services that have a name starting with "ABC":
"NAMING-REQUEST,signature,ABC*,pollux,9999,XQEWRS"
announce ::= {"NAMING-ANNOUNCE" | "NAMING-UNANNOUNCE"} "," name
request ::= "NAMING-REQUEST" ","
signature "," {name | "*"}
response ::= "NAMING-RESPONSE" ","
signature "," name, "," host "," port "," key
signatue ::= a unique client identifier (string)
name ::= a remote object name (string)
host ::= a hostname or ip (string)
port ::= a port number (string)
key ::= a key, that when combined with the host & port
allows a client to access a remote object at
that location (string)
string ::= any sequence of characters that does not include a comma
This sections describes the required behavior for each command. This is the behavior you will be graded on, and this is the behavoir required for the next part of the project. You should be mainting at least two mappings, one of names to locally bound objects, another of names for remotely-bound objects to information about where those objects can be found. This is the same as in the first part of the project.
NAMING-ANNOUNCE,aSignature,anObject,pollux,9999,XQEWRSIf there is a failure with bind() or rebind() this command should not be sent.
NAMING-UNANNOUNCE,aSignature,anObjectIf there is a failure with unbind() or rebind() this command should not be sent.
NAMING-REQUEST,aSignature,anObjectAfter sending this request, the client should pause for a few seconds to allow some time for a response.
When your naming service first starts it should send a request for all remotely bound objects "*".
NAMING-REQUEST,aSignature,*This initializes your mapping of remote objects. Your naming-service will discover all the remote objects it didn't hear announcements for (because it wasn't started yet) as soon as it starts. From this point on, it will see ANNOUNE & UNANNOUNCE commands and will update your mappings accordingly. You no longer need to pause during lookup()s and list()s.
An attempt to discover any remote objects, bound to a name that starts with "anObject", in another process is made because Naming.list("anObject*") was invoked. A request should now be sent.
NAMING-REQUEST,aSignature,anObject*
NAMING-RESPONSE,aSignature,anObject,pollux,9999,XQEWRSIf the name does not match any locally-bound object, the naming service remains silent.
Abbreviated Commands: Map Contents:
N/A (initial) {}
// First response seen
NAMING-RESPONSE,anObject,... { anObject -> pollux,9999,XQEWRS }
// Second response seen
NAMING-RESPONSE,anotherObject,... { anObject -> pollux,9999,XQEWRS
anotherObject -> pollux,9999,XQEWRS }
// anObject is unannounced
NAMING-UNANNOUNCE,anObject { anotherObject -> pollux,9999,XQEWRS }
// anObject is announced at a different location
NAMING-ANNOUNCE,anObject { anotherObject -> pollux,9999,XQEWRS
anObject -> hadar,4444,XQEWRS }
By simply inserting this information into a map, you can easily keep your
local cache up to date. When Naming.lookup() is invoked, check the local
bindings first, if that fails, check the cache - if that successed use the
information there to connect to marshalling service and get the remote object
reference.
DO NOT establish connections to every object you see but cache that information instead, since that wastes alot of resources.
The unsolicited NAMING-ANNOUNCE and NAMING-UNANNOUNCE commands keep the information a naming service has about remote object fresh. The removes a great deal of the delay between each request. Next, we will create a distribution service that distributes a work load over another group or services class servants. These servants are discovered using our protocol. They can be start started and stopped freely, with out having to perform any extra coordination with the distribution- that problem is abstracted away by the discovery protocol.
This part of the project is worth 25% of the whole project. However, you should keep in mind that this part of the project will be used in the next; so it is to your advantage to start and complete this early and correctly. Grading is based on the completeness (each command should be implemented) and correctness (each command should behave as described) of each command in the protocol.
There will NO extensions for this assignment. Late submissions will earn ZERO points.
A skeleton project is provided with that will help you organize your code. You must use this format for the project. It requires all implementation code to placed into one package and all test and demo programs to be placed in another package. The Makefile is taken care of and all you'll need to do is to place your code in the correct places.