Hello,

I would like to use the LeaseRenewalManager to renew the lease every 30 seconds 
(desiredExpiration=Lease.FOREVER, renewDuration=30000).
I notice that the first renewal is delayed based on the server's maxEventLease 
and the renewDuration kicks in only after subsequent renewals.
Below is the output of the reproduction code (notice how the lease is first 
renewed after 2.5 minutes instead of 30 seconds). In this case the mock 
maxEventLease is 5 minutes thus the lease is renewed after 5/2=2.5 minutes.
The question is - what is the best way to add this functionality to the 
LeaseRenewalManager.

10/07/2012 13:18:51 Main main
INFO: Starting... Press any key to abort
10/07/2012 13:23:14 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000
10/07/2012 13:23:40 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000
10/07/2012 13:24:06 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000
10/07/2012 13:24:33 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000
10/07/2012 13:24:59 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000
10/07/2012 13:25:25 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000
10/07/2012 13:25:51 Main$MockEventLease doRenew
INFO: doRenew(duration=30000) returns 30000

Background Information:
The motivation for this is the way the Registrar handles event notifications.
When the Registrar fails to send a notification to a listener due to a 
temporary network glitch, it assumes the listener is no longer available and 
cancels the event lease.
The listener may not detect the temporary network glitch and would remain 
oblivious to the fact that it is no longer registered for events.
The fix is for the listener to send lease renew requests more often to the 
Registrar (and to get an UnknkownLeaseException).
Thus the motivation for setting renewDuration to 30 seconds.

Reproduction code for the LeaseRenewalManager renewDuration behavior is pasted 
below.

Any help would be appreciated,
Itai

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import net.jini.config.AbstractConfiguration;
import net.jini.config.ConfigurationException;
import net.jini.core.lease.Lease;
import net.jini.core.lease.UnknownLeaseException;
import net.jini.core.lookup.ServiceID;
import net.jini.id.Uuid;
import net.jini.lease.DesiredExpirationListener;
import net.jini.lease.LeaseListener;
import net.jini.lease.LeaseRenewalEvent;
import net.jini.lease.LeaseRenewalManager;

import com.sun.jini.reggie.EventLease;
import com.sun.jini.reggie.Registrar;
import com.sun.jini.thread.TaskManager;

public class Main {

       private static final Logger logger = Logger.getLogger("test-renew");
       private static final long MAX_EVENT_LEASE = TimeUnit.MINUTES.toMillis(5);
    private static final long RENEW_BATCH_TIME_WINDOW = 
TimeUnit.MINUTES.toMillis(5);
       private static final long ROUND_TRIP_TIME = TimeUnit.SECONDS.toMillis(3);
       private static final long RENEW_DURATION = TimeUnit.SECONDS.toMillis(30);

       public static void main(String[] args) throws IOException, 
ConfigurationException {

             LeaseRenewalManager lrm = new LeaseRenewalManager(new 
ConfigurationMock());

             Lease lease = 
MockEventLease.getInstance(System.currentTimeMillis() + MAX_EVENT_LEASE);

             long desiredDuration = Lease.FOREVER;
             long renewDuration = RENEW_DURATION;
             lrm.renewFor(lease,desiredDuration, renewDuration, new 
LeaseListenerMock());
             logger.info("Starting... Press any key to abort");
             System.in.read();
       }

       private final static class MockEventLease extends EventLease {

             MockEventLease(Registrar server, ServiceID registrarID, long 
eventID,
                           Uuid leaseID, long expiration) {
                    super(server, registrarID, eventID, leaseID, expiration);
             }

             private static final long serialVersionUID = 1L;

             public void cancel() throws UnknownLeaseException, RemoteException 
{
                    logger.info("cancel()");
             }

             protected long doRenew(long duration)
                           throws UnknownLeaseException, RemoteException
           {
                    long actualDuration = Math.min(duration, MAX_EVENT_LEASE);
                    logger.info("doRenew(duration="+duration+") returns " + 
actualDuration);
              return actualDuration;
           }

             static EventLease getInstance(long expiration)
               {
                    return new MockEventLease(null, new ServiceID(1,1),1,new 
Uuid(1,1),expiration);
               }
       }

       private final static class LeaseListenerMock implements LeaseListener , 
DesiredExpirationListener {

             /* When lease renewal fails, we discard the proxy  */
             public void notify(LeaseRenewalEvent e) {
                    logger.info("notify(e="+e+")");
             }

             @Override
             public void expirationReached(LeaseRenewalEvent e) {
                    logger.info("expirationReached(e="+e+")");

             }
       }

       private final static class ConfigurationMock extends 
AbstractConfiguration {

             private static final String LRM = 
"net.jini.lease.LeaseRenewalManager";

             Map<String,Object> properties = new HashMap<String,Object>();

             ConfigurationMock() {
                    setEntry(LRM, "renewBatchTimeWindow", new 
Primitive(RENEW_BATCH_TIME_WINDOW));
                    setEntry(LRM, "roundTripTime", new 
Primitive(ROUND_TRIP_TIME));
                    setEntry(LRM, "taskManager", new TaskManager(11, 1000 * 15, 
1.0f));
             }

             @Override
             protected Object getEntryInternal(String component, String name,
                           Class type, Object data) throws 
ConfigurationException {

                    String key = key(component, name);
                    if (properties.containsKey(key)) {
                           return properties.get(key);
                    }
                    return data;
             }

             private void setEntry(String component, String name, Object value) 
{
                    properties.put(key(component, name),value);
             }

             private String key(String component, String name) {
                    return component+"."+name;
             }


       }
}

Reply via email to