AMQP-183: tweak synchronized block to try and avoid race where channel is closed before it is used

This commit is contained in:
Dave Syer
2011-07-26 13:45:26 +01:00
parent afa7d23d15
commit 9e710f9fa8
2 changed files with 12 additions and 9 deletions

View File

@@ -284,25 +284,26 @@ public class CachingConnectionFactory extends AbstractConnectionFactory {
// Handle getTargetChannel method: return underlying Channel.
return this.target;
} else if (methodName.equals("isOpen")) {
// Handle isOpen method: we are closed if the target is
// Handle isOpen method: we are closed if the target is closed
return this.target != null && this.target.isOpen();
}
try {
if (this.target == null || !this.target.isOpen()) {
this.target = null;
synchronized (targetMonitor) {
if (this.target == null) {
this.target = createBareChannel(transactional);
}
}
}
return method.invoke(this.target, args);
synchronized (targetMonitor) {
if (this.target == null) {
this.target = createBareChannel(transactional);
}
return method.invoke(this.target, args);
}
} catch (InvocationTargetException ex) {
if (!this.target.isOpen()) {
if (this.target == null || !this.target.isOpen()) {
// Basic re-connection logic...
this.target = null;
logger.debug("Detected closed channel on exception. Re-initializing: " + target);
synchronized (targetMonitor) {
if (!this.target.isOpen()) {
if (this.target == null) {
this.target = createBareChannel(transactional);
}
}

View File

@@ -240,6 +240,8 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
container = createContainer(queue.getName(), new ManualAckListener(latch), connectionFactory);
for (int i = 0; i < messageCount; i++) {
template.convertAndSend(queue.getName(), i + "foo");
// Give the listener container a chance to steal the connection from the template
Thread.sleep(200);
}
int timeout = getTimeout();