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
// info@rabbitmq.com.
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}.
@@ -142,8 +143,8 @@ public RpcClient(RpcClientParams params) throws
142
143
* Private API - ensures the RpcClient is correctly open.
143
144
* @throws IOException if an error is encountered
144
145
*/
145
- public void checkConsumer () throws IOException {
146
- if (_consumer == null ) {
146
+ private void checkNotClosed () throws IOException {
147
+ if (this . closed . get () ) {
147
148
throw new EOFException ("RpcClient is closed" );
148
149
}
149
150
}
@@ -154,11 +155,8 @@ public void checkConsumer() throws IOException {
154
155
*/
155
156
@ Override
156
157
public void close () throws IOException {
157
- if (_consumer != null ) {
158
- final String consumerTag = _consumer .getConsumerTag ();
159
- // set it null before calling basicCancel to make this method idempotent in case of IOException
160
- _consumer = null ;
161
- _channel .basicCancel (consumerTag );
158
+ if (this .closed .compareAndSet (false , true )) {
159
+ _channel .basicCancel (_consumer .getConsumerTag ());
162
160
}
163
161
}
164
162
@@ -176,16 +174,15 @@ public void handleShutdownSignal(String consumerTag,
176
174
for (Entry <String , BlockingCell <Object >> entry : _continuationMap .entrySet ()) {
177
175
entry .getValue ().set (signal );
178
176
}
179
- _consumer = null ;
177
+ closed . set ( true ) ;
180
178
}
181
179
}
182
180
183
181
@ Override
184
182
public void handleDelivery (String consumerTag ,
185
183
Envelope envelope ,
186
184
AMQP .BasicProperties properties ,
187
- byte [] body )
188
- throws IOException {
185
+ byte [] body ) {
189
186
synchronized (_continuationMap ) {
190
187
String replyId = properties .getCorrelationId ();
191
188
BlockingCell <Object > blocker =_continuationMap .remove (replyId );
@@ -216,7 +213,7 @@ public Response doCall(AMQP.BasicProperties props, byte[] message)
216
213
217
214
public Response doCall (AMQP .BasicProperties props , byte [] message , int timeout )
218
215
throws IOException , ShutdownSignalException , TimeoutException {
219
- checkConsumer ();
216
+ checkNotClosed ();
220
217
BlockingCell <Object > k = new BlockingCell <Object >();
221
218
String replyId ;
222
219
synchronized (_continuationMap ) {
0 commit comments