Recommendations for working with LookupCache

Patrick Wright <[email protected]>
Newsgroups gmane.comp.java.sun.jini
Message-ID <[email protected]>
Hi

We've been exploring Jini for about six months. This email is to
gather feedback on what pattern is recommended for handling lookup on
services that may disappear or reappear over time.

The case is that we have a client (web server) which performs a lookup
for a given service using a ServiceDiscoveryManager and a LookupCache.
The Jini configuration in this case is very simple: there is one group
we associate services with, and currently only one service we are
trying to bring online in this server setup. The service is accessed
via a thin (remoting) proxy. There are usually two LUS instances, one
central one, and one launched in the same process as the service
itself, as a backup. Both LUS are associated only with the same,
single group.

On the client side, lookup is performed in a sort of factory class,
that is, all threads in the webserver use the same lookup factory
instance. The lookup factory initializes the SDM and lookup cache on
startup, and uses these throughout its lifespan.

The situation arose where the service instance was brought down, and
then restarted. The service did not attempt to cancel its own lease,
and thus service-instance-1 remained in the LUS until its lease
expired. The service registration is configured such that a new,
unique service id is granted by the LUS, that is, service ids are not
reused. In a simple test setup I created to understand the behavior,
the lookup cache retained the reference both to service-instance-1
(I-1) and service-instance-2 (I-2) even if the discard(service) method
was called on the cache. This is problematic, since without any
additional checks it is possible that either I-1 or I-2 would then be
returned from the lookup factory, even if I-1 was no longer available
(referred to a non-existing service instance).

It is OK if the service is temporarily unavailable; the client
processes can handle that gracefully. However, if a new instance of
the service is available, we would like to use that, and no longer try
to access the service using the old registration.

I can't find any way to do this using the standard Jini classes
themselves. My current approach, which appears to work in a simple
test, is that, if a service call fails with a remote exception, the
lookup factory is notified, and the factory stores the reference to
the service (by service id) in a WeakHashMap. The LookupCache is then
configured with a ServiceItemFilter that checks the map in the
check(ServiceItem) method. If the service discovered in the cache is
in the map, it is skipped.

At some point, the lease on the service will expire from the LUS, the
cache will receive a service-removed event, and there won't be any
more invalid references. The entries in the invalid-service-item map
will be garbage collected, possibly before the lease expires, or
possibly after. There's thus the chance that the entry in the map
could be GC'd before the lease expires, causing another failed call to
the service, but the setup seems simpler to code and test than, say, a
List with a cleanup thread and timeout period.

I appreciate any feedback on this approach or suggestions for
alternatives. FWIW, I haven't been able to find any documentation on
actual recommended practices or patterns for handling unreliability in
distributed services, just a lot of warnings about unreliability :).
I'm interested in this case in recommended, best practices.

Thanks
Patrick

--------------------------------------------------------------------------
Getting Started:     http://www.jini.org/wiki/Category:Getting_Started
Community Web Site:  http://jini.org
jini-users Archive:  http://archives.java.sun.com/archives/jini-users.html
Unsubscribing:       email "signoff JINI-USERS"  to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.