Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
202
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

Another way Jini provides flexibility and ease of use is in how the lookup services are discovered. Although it is possible to specify on what machine(s) a lookup service is running, lookup services can be located dynamically at runtime. So neither the Jini service nor the service consumer need to know where the lookup service is running.

Within Jini the part of a Jini service that is transported across the network is called the Service proxy even though that object may be the full Jini service.

Leases

One of Jini’s most distinguishing features is leases. Every resource a service consumer uses, or is interested in, is leased. A lease is an acknowledgement from the user of the service to the service (holder of the resource) that it is still interested in that particular resource. The lease has a duration after which the lease expires and the resource can be reclaimed. If the service wants to continue to use the resource it has to renew the lease. If the service consumer fails to renew the lease (no longer interested, network failure, and so on), the resource can be reclaimed and re-used.

The lease is not a guarantee. A service consumer can faithfully maintain the lease, but the lease can still fail. The service can cancel leases and free resources whenever it sees fit. The recommendation here is of course that the service should only do that when necessary. It can even happen while the service consumer is using the service. However, lease failure is not as devastating as it may seem. You have already recognized that the network is unreliable, so the service consumer has to be prepared to deal with the unavailability.

Suppose the leased resource is a telephone line service and the service has 10 phone lines available. Normally when those 10 lines are in use and a new line is requested, it will be unavailable. But suppose a fire has broken out, the need for a phone line is top priority. The phone line service cancels the lease on one of the phone lines, claims the resource (the phone line) and makes it available for the call to the fire department.

The lease concept is almost everywhere. When a service registers with the lookup service, one of the things the service receives back is a net.jini.core.lease.Lease instance. The service uses that object to cancel or renew the lease it has on the lookup service. When the service fails to renew the lease (or cancels it), it will be removed from the lookup service. This practice keeps the lookup service up to date.

Distributed Events

The traditional Java event handling is not suitable for distributed events. One reason is that not a single method in a listener interface throws a RemoteException, which is required for the listener to be in another address space. Furthermore, the event objects keep a reference to the source. If that source is a GUI component, that component has to be serialized to be sent across the network. The trouble is that this results in the entire graphical user interface being serialized and sent, because all components keep a reference to their parent. In distributed programming the objects have to be as small as possible. The last reason is that the current event handling system does not support leases.

The Jini event handling system has to keep the uncertainty of the network in mind. Instead of having many different listener interfaces, Jini only provides one, net.jini.core.event.EventListener, with only one

listener method notify(net.jini.core.event.RemoteEvent re). And the notify method throws two exceptions: UnknownEventException and RemoteException.

The RemoteEvent is intended to be as small as possible, while still carrying the information required by the listener. It extends from java.util. EventObject, so it contains a source (the remote service), an event ID, a handback object, and a sequence number. The event ID serves as an identifier to the specific events the listener has registered to. The handback object is, as the name suggests, the object that the listener provides when registering and that the event source hands back to listener when the event occurs (see “Pattern Use” in this section). Finally the sequence number is provided for the uncertainty in the network. Events could arrive out of order or some may just disappear. It is up to the listener what action to take if events arrive out of order.

The event ID and the sequence number are unknown to the listener before registering. When the listener registers, the event source returns an instance of net.jini.core.event.EventRegistration, which contains the eventID, the current sequence number, a Lease object, and a reference to the source.

Pattern Use

HOPP (see page 189): When a Jini client (either a service wanting to register or a service consumer wanting to look a service up) wants to use lookup service, it first locates one or more instances through the discovery

208

protocols. It can use a LookupLocator, a LookupDiscovery, or a LookupLocatorDiscovery to discover a

lookup service.

When the client has discovered a lookup service it receives an instance of a ServiceRegistrar. The ServiceRegistrar is very likely to be a remote object and the instance received is a proxy to that remote object.

Every service in Jini has a unique ID. A lookup service is a Jini service, so it has an unique ID. That ID should be received by the service once and afterwards remembered whenever it restarts. Although the ServiceRegistrar proxy forwards most calls to

the remote object it doesn't make sense to make an expensive remote call when the result doesn’t change. Therefore the service proxy keeps an attribute with the value of the service ID of the lookup service.

Proxy (see page 197): The meaning of a proxy in Jini is broader than the Proxy design pattern. In the Proxy design pattern, a proxy is a placeholder to another object. In Jini the part of the service that is downloaded to the service consumer is called the service proxy. But that service proxy might very well be the full service, completely transparent to the consumer.

Observer (see page 94): When a service consumer is looking for a specific type of service, the service might not be available at the time of the request. It would be inefficient to repeat the lookup until a service is found. It is much better to do the lookup once and be notified when a change has occurred. To do that the client uses the notify method on the ServiceRegistrar object. Because this involves remote event handling the consumer supplies the template for the service it is looking for, the handback object, the remote listener instance to be notified of the change, a requested lease duration and the type of transitions.

209