Skip to content

Commit bb252ff

Browse files
Test that recovery starts after all connection shutdown hooks have executed
Note: we cannot guarantee that they'd have *finished* by the time recovery starts. Provided that ShutdownListeners are typically basic sequential functions, that'll be the case most of the time. Fixes #135
1 parent 62898ad commit bb252ff

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

src/main/java/com/rabbitmq/client/impl/recovery/AutorecoveringConnection.java

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.rabbitmq.client.ShutdownListener;
1212
import com.rabbitmq.client.ShutdownSignalException;
1313
import com.rabbitmq.client.TopologyRecoveryException;
14+
import com.rabbitmq.client.impl.AMQConnection;
1415
import com.rabbitmq.client.impl.ConnectionParams;
1516
import com.rabbitmq.client.ExceptionHandler;
1617
import com.rabbitmq.client.impl.FrameHandlerFactory;
@@ -254,6 +255,13 @@ public void abort(int timeout) {
254255
delegate.abort(timeout);
255256
}
256257

258+
/**
259+
* Not supposed to be used outside of automated tests.
260+
*/
261+
public AMQConnection getDelegate() {
262+
return delegate;
263+
}
264+
257265
/**
258266
* @see com.rabbitmq.client.Connection#getCloseReason()
259267
*/

src/test/java/com/rabbitmq/client/test/functional/ConnectionRecovery.java

+40-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.rabbitmq.client.test.functional;
22

33
import com.rabbitmq.client.*;
4-
import com.rabbitmq.client.impl.recovery.AutorecoveringChannel;
5-
import com.rabbitmq.client.impl.recovery.AutorecoveringConnection;
4+
import com.rabbitmq.client.impl.AMQConnection;
5+
import com.rabbitmq.client.impl.recovery.*;
66
import com.rabbitmq.client.Recoverable;
77
import com.rabbitmq.client.RecoveryListener;
8-
import com.rabbitmq.client.impl.recovery.ConsumerRecoveryListener;
9-
import com.rabbitmq.client.impl.recovery.QueueRecoveryListener;
108
import com.rabbitmq.client.test.BrokerTestCase;
119
import com.rabbitmq.tools.Host;
1210

@@ -90,6 +88,44 @@ public void testConnectionRecoveryWithDisabledTopologyRecovery()
9088
}
9189
}
9290

91+
// see https://github.com/rabbitmq/rabbitmq-java-client/issues/135
92+
public void testThatShutdownHooksOnConnectionFireBeforeRecoveryStarts() throws IOException, InterruptedException {
93+
final List<String> events = new ArrayList<String>();
94+
final CountDownLatch latch = new CountDownLatch(1);
95+
connection.addShutdownListener(new ShutdownListener() {
96+
public void shutdownCompleted(ShutdownSignalException cause) {
97+
events.add("shutdown hook 1");
98+
}
99+
});
100+
connection.addShutdownListener(new ShutdownListener() {
101+
public void shutdownCompleted(ShutdownSignalException cause) {
102+
events.add("shutdown hook 2");
103+
}
104+
});
105+
// note: we do not want to expose RecoveryCanBeginListener so this
106+
// test does not use it
107+
((AutorecoveringConnection)connection).getDelegate().addRecoveryCanBeginListener(new RecoveryCanBeginListener() {
108+
@Override
109+
public void recoveryCanBegin(ShutdownSignalException cause) {
110+
events.add("recovery start hook 1");
111+
}
112+
});
113+
((AutorecoveringConnection)connection).addRecoveryListener(new RecoveryListener() {
114+
@Override
115+
public void handleRecovery(Recoverable recoverable) {
116+
latch.countDown();
117+
}
118+
});
119+
assertTrue(connection.isOpen());
120+
closeAndWaitForRecovery();
121+
assertTrue(connection.isOpen());
122+
assertEquals("shutdown hook 1", events.get(0));
123+
assertEquals("shutdown hook 2", events.get(1));
124+
assertEquals("recovery start hook 1", events.get(2));
125+
connection.close();
126+
wait(latch);
127+
}
128+
93129
public void testShutdownHooksRecoveryOnConnection() throws IOException, InterruptedException {
94130
final CountDownLatch latch = new CountDownLatch(2);
95131
connection.addShutdownListener(new ShutdownListener() {

0 commit comments

Comments
 (0)