Using the Service Discovery Manager
Version 1.00 – May 14, 2004
Example logo
SDM examples main page
prev | next

Example 4: Advanced Lookup Using the LookupCache

Example 3 uses a LookupCache, but doesn't seem to provide any additional functionality over Example 1, which uses a basic lookup method. In fact, the LookupCache actually doesn't provide much of an advantage for the example programs used so far. The benefits are greatest in programs that require long-lived service references, where the possibility of a service crash or network failure becomes more likely. Although such a real world example is outside the scope of this document, the following example attempts to highlight some important issues and possible solutions using the service discovery manager.

Example 4 attempts to find an "unreliable" service and invoke its only remote method in a loop. Remote exceptions, if any, are handled according to a simple retry strategy.

Please review the code in the files AdvancedLookupCache.java, UnreliableService.java, and UnreliableServiceImpl.java. A detailed explanation of that code follows.

Dissecting the Example

The code in Sections 1 through 3 is essentially the same as the last example, except that the template (in section 2) now matches instances of UnreliableService instead of TransactionManager.

The code in Section 4 uses a blocking lookup method to wait for at least one UnreliableService reference to become available. If none becomes available, a message is displayed indicating that a service could not be found before the time-out value was reached, and the program exits.

The code in Section 5 then uses the initial service reference to invoke the service's only remote method from within a loop. Remote exceptions, if any, are handled by a simple retry strategy. First, the current service reference is discarded, which tells the cache to remove that service from the cache so that it does not appear in any subsequent lookup query (unless it is rediscovered, see Section SD.5.5.1 of the Jini Service Discovery Utilities Specification). Then a new lookup query is performed to obtain a new service reference, if any. This loop continues until the maximum number of attempts is exhausted or there are no more service references.

The code in Section 6 calls terminate on the service discovery manager in order to initiate any cleanup duties. Note that this will also call the individual terminate methods for each active cache created by this service discovery manager object.

Running the Example

The example can be run on a UNIX platform by doing the following in one window:

	$ cd bin12 (or bin20 for Jini 2.0 environments)
	$ start_unreliable_service.sh

The example can be run on a Windows platform by doing the following:

	$ cd bat12 (or bat20 for Jini 2.0 environments)
	$ start_unreliable_service.bat

And by doing the following in a different window:

	$ cd bin12 (or bin20 for Jini 2.0 environments)
	$ run_advanced_lookup_cache.sh

The example can be run on a Windows platform by doing the following:

	$ cd bat12 (or bat20 for Jini 2.0 environments)
	$ run_advanced_lookup_cache.bat

Assuming there is at least one publicly available lookup service and it contains two references to an UnreliableService, you should see output similar to the following output from the unreliable service:

$ start_unreliable_service.sh
+ hostname 
CODEBASEHOST=pion
+ . JINI_HOME.sh 
EXJINIHOME=/files/jini1_2_1
+ java -Djava.security.policy=../policy/policy.all -Djava.rmi.server.codebase=http://pion:8082/UnreliableService-dl.jar -jar ../lib12/UnreliableService.jar 
Service <2>: registered with LUS as 554e8dba-8f37-4372-82ee-f10a8f881f06
Service <1>: registered with LUS as 33df1869-e646-4ab3-b630-c0fe50e49198

When the run_basic_lookup_cache script (or batch) file is run, something similar to the following should appear in that window:

$ run_advanced_lookup_cache.sh
+ hostname 
CODEBASEHOST=pion
+ . JINI_HOME.sh 
EXJINIHOME=/files/jini1_2_1
+ java -Djava.security.policy=../policy/policy.all -Djava.rmi.server.codebase=http://pion:8081/sdm-dl.jar -jar ../lib12/AdvancedLookupCache.jar 
Creating ServiceDiscoveryManager ...
Creating ServiceTemplate for a com.sun.jini.example.sdm.ex1.UnreliableService instance
Creating LookupCache
Attempting service lookup for a com.sun.jini.example.sdm.ex1.UnreliableService instance
Obtained service, id: 33df1869-e646-4ab3-b630-c0fe50e49198
UnreliableService::unreliableIdempotentMethod() -> 1
UnreliableService::unreliableIdempotentMethod() -> 2
UnreliableService::unreliableIdempotentMethod() -> 3
Caught RemoteException: java.rmi.NoSuchObjectException: no such object in table
Discarding old service reference
Obtained new service, id: 554e8dba-8f37-4372-82ee-f10a8f881f06
UnreliableService::unreliableIdempotentMethod() -> 1
UnreliableService::unreliableIdempotentMethod() -> 2
UnreliableService::unreliableIdempotentMethod() -> 3
Caught RemoteException: java.rmi.NoSuchObjectException: no such object in table
Discarding old service reference
No more available service references

The output above shows three successful method invocation attempts before the receipt of a RemoteException on the fourth attempt. At this point, the program discards the current service reference and initiates a lookup for another reference through the lookup cache object. A new reference is found and the loop is repeated. After the second RemoteException is received, no more service references are available, and the loop exits.

And something similar to the following should appear in the window running the unreliable service:

Service <1>: unreliableIdempotentMethod() called 1 times.
Service <1>: unreliableIdempotentMethod() called 2 times.
Service <1>: unreliableIdempotentMethod() called 3 times.
Service <1>:    unexporting service object: 1
Service <2>: unreliableIdempotentMethod() called 1 times.
Service <2>: unreliableIdempotentMethod() called 2 times.
Service <2>: unreliableIdempotentMethod() called 3 times.
Service <2>:    unexporting service object: 2

The above output indicates that the client-side application obtained a reference to Service <1> and called its unreliableIdempotentMethod method three times. The third attempt also unexports the service object causing any subsequent client invocations to result in a RemoteException. The client retry strategy simply initiates a new lookup call for an UnreliableService, the client obtains a reference to Service <2>, and then the same process is repeated.

Note that the services are no longer available after this point. They will have to be re-created in order to successfully run this example again.

SDM examples main page
prev | next
Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.