Added separately configurable initial delay for timeout tasks on InactivityMonitor

git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@638910 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Davies 2008-03-19 16:07:54 +00:00
parent c18b583020
commit f55923619d
6 changed files with 71 additions and 30 deletions

View File

@ -259,10 +259,21 @@ public class WireFormatInfo implements Command, MarshallAware {
return l == null ? 0 : l.longValue(); return l == null ? 0 : l.longValue();
} }
public void seMaxInactivityDuration(long maxInactivityDuration) throws IOException { public void setMaxInactivityDuration(long maxInactivityDuration) throws IOException {
setProperty("MaxInactivityDuration", new Long(maxInactivityDuration)); setProperty("MaxInactivityDuration", new Long(maxInactivityDuration));
} }
public long getMaxInactivityDurationInitalDelay() throws IOException {
Long l = (Long)getProperty("MaxInactivityDurationInitalDelay");
return l == null ? 0 : l.longValue();
}
public void setMaxInactivityDurationInitalDelay(long maxInactivityDurationInitalDelay) throws IOException {
setProperty("MaxInactivityDurationInitalDelay", new Long(maxInactivityDurationInitalDelay));
}
/** /**
* @throws IOException * @throws IOException
*/ */

View File

@ -36,7 +36,8 @@ public class OpenWireFormatFactory implements WireFormatFactory {
private boolean cacheEnabled = true; private boolean cacheEnabled = true;
private boolean tightEncodingEnabled = true; private boolean tightEncodingEnabled = true;
private boolean sizePrefixDisabled; private boolean sizePrefixDisabled;
private long maxInactivityDuration = 30 * 1000; private long maxInactivityDuration = 30*1000;
private long maxInactivityDurationInitalDelay = 10*1000;
private int cacheSize = 1024; private int cacheSize = 1024;
public WireFormat createWireFormat() { public WireFormat createWireFormat() {
@ -49,7 +50,8 @@ public class OpenWireFormatFactory implements WireFormatFactory {
info.setTcpNoDelayEnabled(tcpNoDelayEnabled); info.setTcpNoDelayEnabled(tcpNoDelayEnabled);
info.setTightEncodingEnabled(tightEncodingEnabled); info.setTightEncodingEnabled(tightEncodingEnabled);
info.setSizePrefixDisabled(sizePrefixDisabled); info.setSizePrefixDisabled(sizePrefixDisabled);
info.seMaxInactivityDuration(maxInactivityDuration); info.setMaxInactivityDuration(maxInactivityDuration);
info.setMaxInactivityDurationInitalDelay(maxInactivityDurationInitalDelay);
info.setCacheSize(cacheSize); info.setCacheSize(cacheSize);
} catch (Exception e) { } catch (Exception e) {
IllegalStateException ise = new IllegalStateException("Could not configure WireFormatInfo"); IllegalStateException ise = new IllegalStateException("Could not configure WireFormatInfo");
@ -125,4 +127,13 @@ public class OpenWireFormatFactory implements WireFormatFactory {
public void setCacheSize(int cacheSize) { public void setCacheSize(int cacheSize) {
this.cacheSize = cacheSize; this.cacheSize = cacheSize;
} }
public long getMaxInactivityDurationInitalDelay() {
return maxInactivityDurationInitalDelay;
}
public void setMaxInactivityDurationInitalDelay(
long maxInactivityDurationInitalDelay) {
this.maxInactivityDurationInitalDelay = maxInactivityDurationInitalDelay;
}
} }

View File

@ -23,6 +23,7 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.activemq.command.KeepAliveInfo; import org.apache.activemq.command.KeepAliveInfo;
import org.apache.activemq.command.WireFormatInfo; import org.apache.activemq.command.WireFormatInfo;
import org.apache.activemq.thread.SchedulerTimerTask; import org.apache.activemq.thread.SchedulerTimerTask;
@ -51,6 +52,7 @@ public class InactivityMonitor extends TransportFilter {
private final AtomicBoolean commandSent = new AtomicBoolean(false); private final AtomicBoolean commandSent = new AtomicBoolean(false);
private final AtomicBoolean inSend = new AtomicBoolean(false); private final AtomicBoolean inSend = new AtomicBoolean(false);
private final AtomicBoolean failed = new AtomicBoolean(false); private final AtomicBoolean failed = new AtomicBoolean(false);
private final AtomicBoolean stopped = new AtomicBoolean(false);
private final AtomicBoolean commandReceived = new AtomicBoolean(true); private final AtomicBoolean commandReceived = new AtomicBoolean(true);
private final AtomicBoolean inReceive = new AtomicBoolean(false); private final AtomicBoolean inReceive = new AtomicBoolean(false);
@ -59,6 +61,7 @@ public class InactivityMonitor extends TransportFilter {
private long readCheckTime; private long readCheckTime;
private long writeCheckTime; private long writeCheckTime;
private long initialDelayTime;
private final Runnable readChecker = new Runnable() { private final Runnable readChecker = new Runnable() {
long lastRunTime; long lastRunTime;
@ -107,7 +110,7 @@ public class InactivityMonitor extends TransportFilter {
} }
public void stop() throws Exception { public void stop() throws Exception {
stopMonitorThreads(); closeDown();
next.stop(); next.stop();
} }
@ -125,12 +128,15 @@ public class InactivityMonitor extends TransportFilter {
} }
ASYNC_TASKS.execute(new Runnable() { ASYNC_TASKS.execute(new Runnable() {
public void run() { public void run() {
try { if (stopped.get() == false) {
KeepAliveInfo info = new KeepAliveInfo(); try {
info.setResponseRequired(true);
oneway(info); KeepAliveInfo info = new KeepAliveInfo();
} catch (IOException e) { info.setResponseRequired(true);
onException(e); oneway(info);
} catch (IOException e) {
onException(e);
}
} }
}; };
}); });
@ -155,9 +161,10 @@ public class InactivityMonitor extends TransportFilter {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("No message received since last read check for " + toString() + "! Throwing InactivityIOException."); LOG.debug("No message received since last read check for " + toString() + "! Throwing InactivityIOException.");
} }
closeDown();
ASYNC_TASKS.execute(new Runnable() { ASYNC_TASKS.execute(new Runnable() {
public void run() { public void run() {
handleException(new InactivityIOException("Channel was inactive for too long: "+next.getRemoteAddress())); onException(new InactivityIOException("Channel was inactive for too long: "+next.getRemoteAddress()));
}; };
}); });
@ -218,15 +225,17 @@ public class InactivityMonitor extends TransportFilter {
synchronized(inSend) { synchronized(inSend) {
inSend.set(true); inSend.set(true);
try { try {
if( failed.get() ) {
closeDown();
throw new InactivityIOException("Channel was inactive for too long: "+next.getRemoteAddress());
}
if (o.getClass() == WireFormatInfo.class) { if (o.getClass() == WireFormatInfo.class) {
synchronized (this) { synchronized (this) {
localWireFormatInfo = (WireFormatInfo)o; localWireFormatInfo = (WireFormatInfo)o;
startMonitorThreads(); startMonitorThreads();
} }
} }
if( failed.get() ) {
throw new InactivityIOException("Channel was inactive for too long: "+next.getRemoteAddress());
}
next.oneway(o); next.oneway(o);
} finally { } finally {
commandSent.set(true); commandSent.set(true);
@ -236,17 +245,18 @@ public class InactivityMonitor extends TransportFilter {
} }
public void onException(IOException error) { public void onException(IOException error) {
if( !failed.getAndSet(true) ) { closeDown();
handleException(error); if (!failed.getAndSet(true)) {
} transportListener.onException(error);
}
} }
private void handleException(IOException error) { private void closeDown() {
if (monitorStarted.get()) { stopped.set(true);
stopMonitorThreads(); if (monitorStarted.get()) {
} stopMonitorThreads();
transportListener.onException(error); }
} }
private synchronized void startMonitorThreads() throws IOException { private synchronized void startMonitorThreads() throws IOException {
if (monitorStarted.get()) { if (monitorStarted.get()) {
@ -260,6 +270,7 @@ public class InactivityMonitor extends TransportFilter {
} }
readCheckTime = Math.min(localWireFormatInfo.getMaxInactivityDuration(), remoteWireFormatInfo.getMaxInactivityDuration()); readCheckTime = Math.min(localWireFormatInfo.getMaxInactivityDuration(), remoteWireFormatInfo.getMaxInactivityDuration());
initialDelayTime = Math.min(localWireFormatInfo.getMaxInactivityDurationInitalDelay(), remoteWireFormatInfo.getMaxInactivityDurationInitalDelay());
if (readCheckTime > 0) { if (readCheckTime > 0) {
monitorStarted.set(true); monitorStarted.set(true);
writeCheckerTask = new SchedulerTimerTask(writeChecker); writeCheckerTask = new SchedulerTimerTask(writeChecker);
@ -271,8 +282,8 @@ public class InactivityMonitor extends TransportFilter {
WRITE_CHECK_TIMER = new Timer("InactivityMonitor WriteCheck"); WRITE_CHECK_TIMER = new Timer("InactivityMonitor WriteCheck");
} }
CHECKER_COUNTER++; CHECKER_COUNTER++;
WRITE_CHECK_TIMER.scheduleAtFixedRate(writeCheckerTask, writeCheckTime,writeCheckTime); WRITE_CHECK_TIMER.scheduleAtFixedRate(writeCheckerTask, initialDelayTime,writeCheckTime);
READ_CHECK_TIMER.scheduleAtFixedRate(readCheckerTask, readCheckTime,readCheckTime); READ_CHECK_TIMER.scheduleAtFixedRate(readCheckerTask, initialDelayTime,readCheckTime);
} }
} }
} }

View File

@ -45,6 +45,7 @@ class BackupTransport extends DefaultTransportListener{
} }
public void setTransport(Transport transport) { public void setTransport(Transport transport) {
this.transport = transport; this.transport = transport;
this.transport.setTransportListener(this);
} }
public URI getUri() { public URI getUri() {
return uri; return uri;

View File

@ -107,9 +107,12 @@ public class FailoverTransport implements CompositeTransport {
public boolean iterate() { public boolean iterate() {
boolean result=false; boolean result=false;
boolean buildBackup=true; boolean buildBackup=true;
if (connectedTransport.get()==null && !disposed) { boolean doReconnect = !disposed;
result=doReconnect(); synchronized(backupMutex) {
buildBackup=false; if (connectedTransport.get()==null && !disposed) {
result=doReconnect();
buildBackup=false;
}
} }
if(buildBackup) { if(buildBackup) {
buildBackups(); buildBackups();
@ -253,6 +256,10 @@ public class FailoverTransport implements CompositeTransport {
started = false; started = false;
disposed = true; disposed = true;
connected = false; connected = false;
for (BackupTransport t:backups) {
t.setDisposed(true);
}
backups.clear();
if (connectedTransport.get() != null) { if (connectedTransport.get() != null) {
transportToStop = connectedTransport.getAndSet(null); transportToStop = connectedTransport.getAndSet(null);

View File

@ -186,7 +186,7 @@ public class InactivityMonitorTest extends CombinationTestSupport implements Tra
}); });
clientTransport.start(); clientTransport.start();
WireFormatInfo info = new WireFormatInfo(); WireFormatInfo info = new WireFormatInfo();
info.seMaxInactivityDuration(1000); info.setMaxInactivityDuration(1000);
clientTransport.oneway(info); clientTransport.oneway(info);
assertEquals(0, serverErrorCount.get()); assertEquals(0, serverErrorCount.get());