[jboss-cvs] JBossRemoting/src/main/org/jboss/remoting ...
Ron Sigal
ron_sigal at yahoo.com
Thu Aug 2 02:33:39 EDT 2007
User: rsigal
Date: 07/08/02 02:33:39
Modified: src/main/org/jboss/remoting Tag: remoting_2_2_0_GA
MicroRemoteClientInvoker.java
Log:
JBREM-783: Reorganized establishLease() and terminateLease().
Revision Changes Path
No revision
No revision
1.7.2.14.4.1 +141 -23 JBossRemoting/src/main/org/jboss/remoting/MicroRemoteClientInvoker.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: MicroRemoteClientInvoker.java
===================================================================
RCS file: /cvsroot/jboss/JBossRemoting/src/main/org/jboss/remoting/MicroRemoteClientInvoker.java,v
retrieving revision 1.7.2.14
retrieving revision 1.7.2.14.4.1
diff -u -b -r1.7.2.14 -r1.7.2.14.4.1
--- MicroRemoteClientInvoker.java 21 Feb 2007 10:57:38 -0000 1.7.2.14
+++ MicroRemoteClientInvoker.java 2 Aug 2007 06:33:39 -0000 1.7.2.14.4.1
@@ -27,7 +27,7 @@
*
* @author <a href="mailto:jhaynie at vocalocity.net">Jeff Haynie</a>
* @author <a href="mailto:telrod at e2technologies.net">Tom Elrod</a>
- * @version $Revision: 1.7.2.14 $
+ * @version $Revision: 1.7.2.14.4.1 $
*/
public abstract class MicroRemoteClientInvoker extends AbstractInvoker implements ClientInvoker
{
@@ -41,6 +41,7 @@
private final Object clientLeaseLock = new Object();
private LeasePinger leasePinger = null;
private String invokerSessionID = new GUID().toString();
+ private Exception leasePingerException;
public MicroRemoteClientInvoker(InvokerLocator locator)
{
@@ -311,24 +312,53 @@
public void terminateLease(String sessionId, int disconnectTimeout)
{
+ // The synchronization of establishLease() and terminateLease() has been
+ // reorganized - see JBREM-783.
+
+ // The process of removing an org.jboss.remoting.Client from a LeasePinger
+ // is now divided into two steps: (1) LeasePinger.removeClient(), which
+ // just removes a reference to the Client in a LeasePinger map, and
+ // (2) leasePinger.disconnectClient(), which sends a message to the server.
+ // Only step (1) takes place inside the synchronization block. If it is
+ // determined in step (1) that the last Client has been removed from the
+ // LeasePinger, then the instance variable leasePinger is set to null.
+ // Once leasePinger is set to null, the next Client that calls
+ // establishLease() will have to create a new LeasePinger, which it will
+ // be able to do without waiting for the completion of the network i/o
+ // performed in terminateLease().
+
+ LeasePinger localPinger = null;
+ boolean isLastClientLease = false;
+
synchronized(clientLeaseLock)
{
+ localPinger = leasePinger;
+
if(leasePinger != null)
{
- leasePinger.setDisconnectTimeout(disconnectTimeout);
- boolean isLastClientLease = leasePinger.removeClient(sessionId);
+ isLastClientLease = leasePinger.removeClient(sessionId);
if(isLastClientLease)
{
+ leasePinger = null;
+ }
+ }
+ }
+
+ if (localPinger != null)
+ {
+ localPinger.setDisconnectTimeout(disconnectTimeout);
+ localPinger.disconnectClient(sessionId);
+
+ if (isLastClientLease)
+ {
try
{
- leasePinger.stopPing();
+ localPinger.stopPing();
}
catch (Exception e)
{
log.error("error shutting down lease pinger");
}
- leasePinger = null;
- }
}
}
}
@@ -349,6 +379,18 @@
public void establishLease(String clientSessionID, Map configuration, long leasePeriod)
throws Throwable
{
+ // The synchronization in establishLease() and terminateLease() has been
+ // reorganized - see JBREM-783.
+
+ // The set of org.jboss.remoting.Client's entering
+ // establishLease() partitioned as follows: (1) the first Client to enter
+ // the synchronization block and find leasePinger == null, and (2) all other
+ // Client's. The first client is responsible for creating the LeasePinger,
+ // including all necessary network i/o, and the other Client's wait until the
+ // LeasePinger has been started. However, the network i/o does not take place
+ // inside the synchronization block. The advantage is that other Client's
+ // can call terminateLease() without being blocked.
+
synchronized (clientLeaseLock)
{
// if already have a lease pinger, then already have a client with an established
@@ -357,7 +399,64 @@
{
leasePinger.addClient(clientSessionID, configuration, leasePeriod);
log.debug(this + " added client with session ID " + clientSessionID + " to the lease pinger");
+
+ if (leasePinger.isStarted())
+ return;
+
+ if (leasePingerException != null)
+ throw leasePingerException;
+
+ while (true)
+ {
+ try
+ {
+ clientLeaseLock.wait();
+ }
+ catch (InterruptedException ignored) {}
+
+ if (leasePinger == null || leasePinger.isStarted())
return;
+
+ if (leasePingerException != null)
+ throw leasePingerException;
+ }
+ }
+ else
+ {
+ leasePingerException = null;
+ leasePinger = new LeasePinger(this, invokerSessionID);
+ }
+ }
+
+ InvocationRequest ir =
+ new InvocationRequest(invokerSessionID, null, "$PING$", null, new HashMap(), null);
+
+ int clientCount;
+ int attemptCount = 0;
+
+ while (true)
+ {
+ Exception tempException = null;
+
+ synchronized (clientLeaseLock)
+ {
+ clientCount = leasePinger.getClients().size();
+ if (attemptCount++ > clientCount)
+ {
+ if (tempException == null)
+ {
+ leasePingerException = new Exception("Error setting up client lease");
+ }
+ else
+ {
+ leasePingerException = tempException;
+ }
+
+ leasePinger.purgeClients();
+ leasePinger = null;
+ clientLeaseLock.notifyAll();
+ throw leasePingerException;
+ }
}
try
@@ -367,9 +466,6 @@
// configuration should NOT be passed as want ping to be specific to client invoker
// and NOT to the client.
- InvocationRequest ir =
- new InvocationRequest(invokerSessionID, null, "$PING$", null, new HashMap(), null);
-
Object ret = invoke(ir);
if (ret instanceof InvocationResponse)
@@ -392,19 +488,41 @@
}
}
- if(trace) { log.trace("server does have leasing enabled (with default lease period of " + defaultLeasePeriod + ") and will start a new lease pinger."); }
+ leasePinger.setDefaultLeasePeriod(defaultLeasePeriod);
+
+ if(trace) { log.trace("server does have leasing enabled (with default lease period of " +
+ defaultLeasePeriod + ") and will start a new lease pinger."); }
- leasePinger = new LeasePinger(this, invokerSessionID, defaultLeasePeriod);
leasePinger.addClient(clientSessionID, configuration, leasePeriod);
+
+ synchronized (clientLeaseLock)
+ {
leasePinger.startPing();
+ clientLeaseLock.notifyAll();
+ return;
}
}
+ else
+ {
+ synchronized (clientLeaseLock)
+ {
+ leasePinger.purgeClients();
+ leasePinger = null;
+ clientLeaseLock.notifyAll();
+ return;
+ }
+ }
+ }
+ else
+ {
+ String message = "Error setting up client lease: invalid response from server: " + ret;
+ tempException = new Exception(message);
+ }
}
catch (Throwable throwable)
{
- Exception e = new Exception("Error setting up client lease");
- e.initCause(throwable);
- throw e;
+ tempException = new Exception("Error setting up client lease");
+ tempException.initCause(throwable);
}
}
}
More information about the jboss-cvs-commits
mailing list