Hey,

Thanks for including the background information, that makes it much easier
to figure out how to answer the question.

In this case, I'm not sure that increasing the frequency of lease renewals
will help you. The same network problems that cause the Registrar to drop a
listener can also foul up the lease renewal process such that it can take a
long time for a renewal request to be processed.

Basically, even though you make a call after about 20 seconds (the LRM
takes some time off the overall lease renewal duration to account for
network roundtrip) it could take substantial time to complete such that you
aren't informed for much longer than the 30 seconds you are after.

I guess the question then is: Why is it important to "know with certainty"
that the lease has expired as soon as possible?

Ultimately, we can't know precisely when the lease expires and when we
figure out that expiry occurred we still have to:

(1) Contact the registrar and recover state.
(2) Register for events that update state recovered in (1).

So our response is always the same, it can just be a little slow hence my
question above: Why do you want to know "more quickly"?

Best,

Dan.

On 10 July 2012 11:41, Itai Frenkel <[email protected]> wrote:

> 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