Skip to content

Commit 5172dc4

Browse files
committed
Do not use transient non-exclusive queue on RabbitMQ 4.3+
Fall back to durable non-exclusive. References rabbitmq/rabbitmq-server#15459
1 parent 8c69d32 commit 5172dc4

3 files changed

Lines changed: 45 additions & 13 deletions

File tree

src/main/java/com/rabbitmq/perf/MulticastParams.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@
3838
import java.util.concurrent.TimeoutException;
3939
import java.util.concurrent.atomic.AtomicReference;
4040
import java.util.stream.Collectors;
41+
import org.slf4j.Logger;
42+
import org.slf4j.LoggerFactory;
4143

4244
public class MulticastParams {
4345

46+
private static final Logger LOGGER = LoggerFactory.getLogger(MulticastParams.class);
47+
4448
private long confirm = -1;
4549
private int confirmTimeout = 30;
4650
private int consumerCount = 1;
@@ -956,23 +960,24 @@ class State {
956960
TopologyRecording topologyRecording = state.topologyRecording;
957961

958962
if (!params.predeclared || !queueExists(connection, qName)) {
963+
boolean durable = params.flags.contains("persistent");
964+
boolean exclusive = params.isExclusive();
965+
boolean autoDelete = params.autoDelete;
966+
967+
if (Utils.atLeast4_3(connection) && !durable && !exclusive) {
968+
LOGGER.warn(
969+
"Non-durable non-exclusive queues are not supported on RabbitMQ 4.3+, "
970+
+ "switching to durable non-exclusive");
971+
durable = true;
972+
}
973+
959974
boolean serverNamed = qName == null || "".equals(qName);
960975
qName =
961976
channel
962-
.queueDeclare(
963-
qName,
964-
params.flags.contains("persistent"),
965-
params.isExclusive(),
966-
params.autoDelete,
967-
params.queueArguments)
977+
.queueDeclare(qName, durable, exclusive, autoDelete, params.queueArguments)
968978
.getQueue();
969979
topologyRecording.recordQueue(
970-
qName,
971-
params.flags.contains("persistent"),
972-
params.isExclusive(),
973-
params.autoDelete,
974-
params.queueArguments,
975-
serverNamed);
980+
qName, durable, exclusive, autoDelete, params.queueArguments, serverNamed);
976981
}
977982
generatedQueueNames.add(qName);
978983
// skipping binding to default exchange,

src/main/java/com/rabbitmq/perf/Utils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,33 @@ static boolean exists(Connection connection, Checker checker) throws IOException
318318
}
319319
}
320320

321+
static boolean atLeast4_3(Connection connection) {
322+
String version = connection.getServerProperties().get("version").toString();
323+
return versionCompare(version, "4.3.0") >= 0;
324+
}
325+
326+
/**
327+
* https://stackoverflow.com/questions/6701948/efficient-way-to-compare-version-strings-in-java
328+
*/
329+
private static int versionCompare(String str1, String str2) {
330+
String[] vals1 = str1.split("\\.");
331+
String[] vals2 = str2.split("\\.");
332+
int i = 0;
333+
// set index to first non-equal ordinal or length of shortest version string
334+
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
335+
i++;
336+
}
337+
// compare first non-equal ordinal number
338+
if (i < vals1.length && i < vals2.length) {
339+
Integer val1 = Integer.valueOf(vals1[i]);
340+
Integer val2 = Integer.valueOf(vals2[i]);
341+
return val1.compareTo(val2);
342+
}
343+
// the strings are equal or one string is a substring of the other
344+
// e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
345+
return Integer.signum(vals1.length - vals2.length);
346+
}
347+
321348
@SuppressWarnings("unchecked")
322349
static InstanceSynchronization defaultInstanceSynchronization(
323350
String id, int expectedInstances, String namespace, Duration timeout, PrintStream out) {

src/test/java/com/rabbitmq/perf/it/ConnectionRecoveryIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ public void shouldRecoverWithPreDeclared(boolean polling, TestInfo info) throws
381381
try (Connection c = connectionFactory.newConnection()) {
382382
Channel ch = c.createChannel();
383383
for (int i = 1; i <= queueCount; i++) {
384-
ch.queueDeclare(String.format(queuePattern, i), false, false, false, null);
384+
ch.queueDeclare(String.format(queuePattern, i), true, false, false, null);
385385
}
386386
}
387387

0 commit comments

Comments
 (0)