LE.3. Example Supporting Classes

The basic Lease interface allows leases to be granted by one object and handed to another as the result of a call that creates or provides access to some leased resource. The goal of the interface is to allow as much freedom as possible in implementation to both the party that is granting the lease (and thus is giving out the implementation that supports the Lease interface) and the party that receives the lease.

However, a number of classes can be supplied that can simplify the handling of leases in some common cases. We will describe examples of these supporting classes and show how these classes can be used with leased resources. Please note that complete specifications for such utilities and services do exist and may differ in some degree from these examples.

LE.3.1. A Renewal Class

One of the common patterns with leasing is for the lease holder to request a lease with the intention of renewing the lease until it is finished with the resource. The period of time during which the resource is needed is unknown at the time of requesting the lease, so the requestor wants the lease to be renewed until an undetermined time in the future. Alternatively, the lease requestor might know how long the lease needs to be held, but the lease holder might be unwilling to grant a lease for the full period of time. Again, the pattern will be to renew the lease for some period of time.

If the lease continues to be renewed, the lease holder doesn’t want to be bothered with knowing about it, but if the lease is not renewed for some reason, the lease holder wants to be notified. Such a notification can be done by using the usual inter-address space mechanisms for event notifications, by registering a lis tener of the appropriate type. This functionality can be supplied by a class with an interface like the following:

class LeaseRenew {
    LeaseRenew(Lease toRenew, 
               long renewTil, 
               LeaseExpireListener listener) {...} 
    void addRenew(Lease toRenew, 
                  long renewTil, 
                  LeaseExpireListener listener) {...} 
    long getExpiration(Lease forLease) 
        throws UnknownLeaseException {...} 
    void setExpiration(Lease forLease, long toExpire) 
        throws UnknownLeaseException {...} 
    void cancel(Lease toCancel) 
        throws UnknownLeaseException {...} 
    void setLeaseExpireListener(Lease forLease, 
                                LeaseExpireListener listener) 
        throws UnknownLeaseException {...} 
    void removeLeaseExpireListener(Lease forLease) 
        throws UnknownLeaseException {...} 
} 

The constructor of this class takes a Lease object, presumably returned from some call that reserved a leased resource; an initial time indicating the time until which the lease should be renewed; and an object that is to be notified if a renewal fails before the time indicated in renewTil. This returns a LeaseRenew object, which will have its own thread of control that will do the lease renewals.

Once a LeaseRenew object has been created, other leases can be added to the set that are renewed by that object using the addRenew call. This call takes a Lease object, an expiration time or overall duration, and a listener to be informed if the lease cannot be renewed prior to the time requested. Internally to the LeaseRenew object, leases that can be batched can be placed into a LeaseMap.

The duration of a particular lease can be queried by a call to the method getExpiration. This method takes a Lease object and returns the time at which that lease will be allowed to expire by the LeaseRenew object. Note that this is different from the Lease.getExpiration method, which tells the time at which the lease will expire if it is not renewed. If there is no Lease object corresponding to the argument for this call being handled by the LeaseRenew object, an UnknownLeaseException will be thrown. This can happen either when no such Lease has ever been given to the LeaseRenew object, or when a Lease object that has been held has already expired or been cancelled. Notice that because this object is assumed to be in the same address space as the object that acquired the lease, we can also assume that it shares the same clock with that object, and hence can use absolute time rather than a duration-based system.

The setExpiration method allows the caller to adjust the expiration time of any Lease object held by the LeaseRenew object. This method takes as arguments the Lease whose time of expiration is to be adjusted and the new expiration time. If no lease is held by the LeaseRenew object corresponding to the first argument, an UnknownLeaseException will be thrown.

A call to cancel will result in the cancellation of the indicated Lease held by the LeaseRenew object. Again, if the lease has already expired on that object, an UnknownLeaseException will be thrown. It is expected that a call to this method will be made if the leased resource is no longer needed, rather than just dropping all references to the LeaseRenew object.

The methods setLeaseExpireListener and removeLeaseExpireListener allow setting and unsetting the destination of an event handler associated with a particular Lease object held by the LeaseRenew object. The handler will be called if the Lease object expires before the desired duration period is completed. Note that one of the properties of this example is that only one LeaseExpireListener can be associated with each Lease.

LE.3.2. A Renewal Service

Objects that hold a lease that needs to be renewed may themselves be activatable, and thus unable to ensure that they will be capable of renewing a lease at some particular time in the future (since they might not be active at that time). For such objects it might make sense to hand the lease renewal duty off to a service that could take care of lease renewal for the object, allowing that object to be deactivated without fear of losing its lease on some other resource.

The most straightforward way of accomplishing this is to hand the Lease object off to some object whose job it is to renew leases on behalf of others. This object will be remote to the objects to which it offers its service (otherwise it would be inactive when the others become inactive) but might be local to the machine; there could even be such services that are located on other machines.

The interface to such an object might look something like:

interface LeaseRenewService extends Remote {
    EventRegistration renew(Lease toRenew, 
                        long renewTil, 
                        RemoteEventListenter notifyBeforeDrop, 
                        MarshalledObject returnOnNotify) 
        throws RemoteException; 
    void onRenewFailure(Lease toRenew, 
                        RemoteEventListenter toNotify, 
                        MarshalledObject returnOnNotify) 
        throws RemoteException, UnknownLeaseException; 
} 

The first method, renew, is the request to the object to renew a particular lease on behalf of the caller. The Lease object to be renewed is passed to the LeaseRenewService object, along with the length of time for which the lease is to be renewed. Since we are assuming that this service might not be on the same machine as the object that acquired the original lease, we return to a duration-based time system, since we cannot assume that the two systems have synchronized clocks.

Requests to renew a Lease are themselves leased. The duration of the lease is requested in the duration argument to the renew method, and the actual time of the lease is returned as part of the EventRegistration return value. While it might seem odd to lease the service of renewing other leases, this does not cause an infinite regress. It is assumed that the LeaseRenewService will grant leases that are longer (perhaps significantly longer) than those in the leases that it is renewing. In this fashion, the LeaseRenewService can act as a concentrator for lease renewal messages.

The renew method also takes as parameters a RemoteEventListener and MarshalledObject objects to be passed to that RemoteEventListener. This is because part of the semantics of the renew call is to register interest in an event that can occur within the LeaseRenewService object. The registration is actually for a notification before the lease granted by the renewal service is dropped. This event notification can be directed back to the object that is the client of the renewal service, and will (if so directed) cause the object to be activated (if it is not already active). This gives the object a chance to renew the lease with the LeaseRenewService object before that lease is dropped.

The second method, onRenewFailure, allows the client to register interest in the LeaseRenewService being unable to renew the Lease supplied as an argument to the call. This call also takes a RemoteEventListener object that is the target of the notification and a MarshalledObject that will be passed as part of the notification. This allows the client to be informed if the LeaseRenewService is denied a lease renewal during the lease period offered to the client for such renewal. This call does not take a time period for the event registration, but instead will have the same duration as the leased renewal associated with the Lease object passed into the call, which should be the same as the Lease object that was sup plied in a previous invocation of the method renew. If the Lease is not known to the LeaseRenewService object, an UnknownLeaseException will be thrown.

There is no need for a method allowing the cancellation of a lease renewal request. Since these requests are themselves leased, cancelling the lease with the LeaseRenewService will cancel both the renewing of the lease and any event registrations associated with that lease.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.171.253