1
- // Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
1
+ // Copyright (c) 2007-2023 VMware, Inc. or its affiliates. All rights reserved.
2
2
//
3
3
// This software, the RabbitMQ Java client library, is triple-licensed under the
4
4
// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2
13
13
// If you have any questions regarding licensing, please contact us at
14
14
15
15
16
-
17
16
package com .rabbitmq .client ;
18
17
19
18
import java .io .ByteArrayInputStream ;
20
19
import java .io .ByteArrayOutputStream ;
21
- import java .io .Closeable ;
22
20
import java .io .DataInputStream ;
23
21
import java .io .DataOutputStream ;
24
22
import java .io .EOFException ;
28
26
import java .util .Map ;
29
27
import java .util .Map .Entry ;
30
28
import java .util .concurrent .TimeoutException ;
29
+ import java .util .concurrent .atomic .AtomicBoolean ;
31
30
import java .util .function .Function ;
32
31
import java .util .function .Supplier ;
33
32
45
44
* It simply provides a mechanism for sending a message to an exchange with a given routing key,
46
45
* and waiting for a response.
47
46
*/
48
- public class RpcClient implements Closeable {
47
+ public class RpcClient implements AutoCloseable {
49
48
50
49
private static final Logger LOGGER = LoggerFactory .getLogger (RpcClient .class );
51
50
@@ -63,6 +62,8 @@ public class RpcClient implements Closeable {
63
62
protected final static int NO_TIMEOUT = -1 ;
64
63
/** Whether to publish RPC requests with the mandatory flag or not. */
65
64
private final boolean _useMandatory ;
65
+ /** closed flag */
66
+ private final AtomicBoolean closed = new AtomicBoolean (false );
66
67
67
68
public final static Function <Object , Response > DEFAULT_REPLY_HANDLER = reply -> {
68
69
if (reply instanceof ShutdownSignalException ) {
@@ -96,7 +97,7 @@ public class RpcClient implements Closeable {
96
97
private String lastCorrelationId = "0" ;
97
98
98
99
/** Consumer attached to our reply queue */
99
- private DefaultConsumer _consumer ;
100
+ private final DefaultConsumer _consumer ;
100
101
101
102
/**
102
103
* Construct a {@link RpcClient} with the passed-in {@link RpcClientParams}.
@@ -227,8 +228,8 @@ public RpcClient(Channel channel, String exchange, String routingKey, int timeou
227
228
* Private API - ensures the RpcClient is correctly open.
228
229
* @throws IOException if an error is encountered
229
230
*/
230
- public void checkConsumer () throws IOException {
231
- if (_consumer == null ) {
231
+ private void checkNotClosed () throws IOException {
232
+ if (this . closed . get () ) {
232
233
throw new EOFException ("RpcClient is closed" );
233
234
}
234
235
}
@@ -239,11 +240,8 @@ public void checkConsumer() throws IOException {
239
240
*/
240
241
@ Override
241
242
public void close () throws IOException {
242
- if (_consumer != null ) {
243
- final String consumerTag = _consumer .getConsumerTag ();
244
- // set it null before calling basicCancel to make this method idempotent in case of IOException
245
- _consumer = null ;
246
- _channel .basicCancel (consumerTag );
243
+ if (this .closed .compareAndSet (false , true )) {
244
+ _channel .basicCancel (_consumer .getConsumerTag ());
247
245
}
248
246
}
249
247
@@ -261,16 +259,15 @@ public void handleShutdownSignal(String consumerTag,
261
259
for (Entry <String , BlockingCell <Object >> entry : _continuationMap .entrySet ()) {
262
260
entry .getValue ().set (signal );
263
261
}
264
- _consumer = null ;
262
+ closed . set ( true ) ;
265
263
}
266
264
}
267
265
268
266
@ Override
269
267
public void handleDelivery (String consumerTag ,
270
268
Envelope envelope ,
271
269
AMQP .BasicProperties properties ,
272
- byte [] body )
273
- throws IOException {
270
+ byte [] body ) {
274
271
synchronized (_continuationMap ) {
275
272
String replyId = properties .getCorrelationId ();
276
273
BlockingCell <Object > blocker =_continuationMap .remove (replyId );
@@ -301,7 +298,7 @@ public Response doCall(AMQP.BasicProperties props, byte[] message)
301
298
302
299
public Response doCall (AMQP .BasicProperties props , byte [] message , int timeout )
303
300
throws IOException , ShutdownSignalException , TimeoutException {
304
- checkConsumer ();
301
+ checkNotClosed ();
305
302
BlockingCell <Object > k = new BlockingCell <Object >();
306
303
String replyId ;
307
304
synchronized (_continuationMap ) {
0 commit comments