Skip to content

Commit dca7226

Browse files
Merge pull request #604 from rabbitmq/rabbitmq-java-client-525-cancel-unknown-consumer
Log warning when receiving basic.cancel for unknown consumer
2 parents 2aff37f + ad69686 commit dca7226

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

src/main/java/com/rabbitmq/client/impl/ChannelN.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ private void releaseChannel() {
386386
Basic.Cancel m = (Basic.Cancel)method;
387387
String consumerTag = m.getConsumerTag();
388388
Consumer callback = _consumers.remove(consumerTag);
389+
// Not finding any matching consumer isn't necessarily an indication of an issue anywhere.
390+
// Sometimes there's a natural race condition between consumer management on the server and client ends.
391+
// E.g. Channel#basicCancel called just before a basic.cancel for the same consumer tag is received.
392+
// See https://github.com/rabbitmq/rabbitmq-java-client/issues/525
389393
if (callback == null) {
390394
callback = defaultConsumer;
391395
}
@@ -402,6 +406,8 @@ private void releaseChannel() {
402406
consumerTag,
403407
"handleCancel");
404408
}
409+
} else {
410+
LOGGER.warn("Could not cancel consumer with unknown tag {}", consumerTag);
405411
}
406412
return true;
407413
} else {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2019 Pivotal Software, Inc. All rights reserved.
2+
//
3+
// This software, the RabbitMQ Java client library, is triple-licensed under the
4+
// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
5+
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
6+
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
7+
// please see LICENSE-APACHE2.
8+
//
9+
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
10+
// either express or implied. See the LICENSE file for specific language governing
11+
// rights and limitations of this software.
12+
//
13+
// If you have any questions regarding licensing, please contact us at
14+
15+
16+
package com.rabbitmq.client.test;
17+
18+
import com.rabbitmq.client.Method;
19+
import com.rabbitmq.client.impl.*;
20+
import org.junit.After;
21+
import org.junit.Before;
22+
import org.junit.Test;
23+
import org.mockito.Mockito;
24+
25+
import java.io.IOException;
26+
import java.util.concurrent.ExecutorService;
27+
import java.util.concurrent.Executors;
28+
29+
public class ChannelNTest {
30+
31+
ConsumerWorkService consumerWorkService;
32+
ExecutorService executorService;
33+
34+
@Before
35+
public void init() {
36+
executorService = Executors.newSingleThreadExecutor();
37+
consumerWorkService = new ConsumerWorkService(executorService, null, 1000, 1000);
38+
}
39+
40+
@After
41+
public void tearDown() {
42+
consumerWorkService.shutdown();
43+
executorService.shutdownNow();
44+
}
45+
46+
@Test
47+
public void serverBasicCancelForUnknownConsumerDoesNotThrowException() throws Exception {
48+
AMQConnection connection = Mockito.mock(AMQConnection.class);
49+
ChannelN channel = new ChannelN(connection, 1, consumerWorkService);
50+
Method method = new AMQImpl.Basic.Cancel.Builder().consumerTag("does-not-exist").build();
51+
channel.processAsync(new AMQCommand(method));
52+
}
53+
54+
@Test(expected = IOException.class)
55+
public void callingBasicCancelForUnknownConsumerThrowsException() throws Exception {
56+
AMQConnection connection = Mockito.mock(AMQConnection.class);
57+
ChannelN channel = new ChannelN(connection, 1, consumerWorkService);
58+
channel.basicCancel("does-not-exist");
59+
}
60+
61+
}

src/test/java/com/rabbitmq/client/test/ClientTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
GeneratedClassesTest.class,
6868
RpcTopologyRecordingTest.class,
6969
ConnectionTest.class,
70-
TlsUtilsTest.class
70+
TlsUtilsTest.class,
71+
ChannelNTest.class
7172
})
7273
public class ClientTests {
7374

0 commit comments

Comments
 (0)