|
18 | 18 |
|
19 | 19 | import static org.assertj.core.api.Assertions.assertThat;
|
20 | 20 |
|
| 21 | +import java.util.ArrayList; |
| 22 | +import java.util.List; |
21 | 23 | import java.util.concurrent.atomic.AtomicBoolean;
|
22 | 24 | import java.util.concurrent.atomic.AtomicInteger;
|
| 25 | +import java.util.concurrent.atomic.AtomicReference; |
23 | 26 |
|
| 27 | +import org.apache.commons.pool2.impl.GenericObjectPool; |
24 | 28 | import org.junit.jupiter.api.Test;
|
25 | 29 |
|
26 | 30 | import org.springframework.amqp.core.Queue;
|
@@ -199,6 +203,70 @@ private void createAndCloseConnectionChannelTxAndChannelNonTx(
|
199 | 203 | connection.close();
|
200 | 204 | }
|
201 | 205 |
|
| 206 | + @Test |
| 207 | + public void evictShouldCloseAllUnneededChannelsWithoutErrors() throws Exception { |
| 208 | + PooledChannelConnectionFactory pcf = new PooledChannelConnectionFactory(new ConnectionFactory()); |
| 209 | + AtomicReference<GenericObjectPool<Channel>> channelsReference = new AtomicReference<>(); |
| 210 | + AtomicReference<GenericObjectPool<Channel>> txChannelsReference = new AtomicReference<>(); |
| 211 | + AtomicInteger swallowedExceptionsCount = new AtomicInteger(); |
| 212 | + pcf.setPoolConfigurer((pool, tx) -> { |
| 213 | + if (tx) { |
| 214 | + channelsReference.set(pool); |
| 215 | + } |
| 216 | + else { |
| 217 | + txChannelsReference.set(pool); |
| 218 | + } |
| 219 | + |
| 220 | + pool.setEvictionPolicy((ec, u, idleCount) -> idleCount > ec.getMinIdle()); |
| 221 | + pool.setSwallowedExceptionListener(ex -> swallowedExceptionsCount.incrementAndGet()); |
| 222 | + pool.setNumTestsPerEvictionRun(5); |
| 223 | + |
| 224 | + pool.setMinIdle(1); |
| 225 | + pool.setMaxIdle(5); |
| 226 | + }); |
| 227 | + |
| 228 | + createAndCloseFiveChannelTxAndChannelNonTx(pcf); |
| 229 | + |
| 230 | + final GenericObjectPool<Channel> channels = channelsReference.get(); |
| 231 | + channels.evict(); |
| 232 | + |
| 233 | + assertThat(channels.getNumIdle()) |
| 234 | + .isEqualTo(1); |
| 235 | + assertThat(channels.getDestroyedByEvictorCount()) |
| 236 | + .isEqualTo(4); |
| 237 | + |
| 238 | + final GenericObjectPool<Channel> txChannels = txChannelsReference.get(); |
| 239 | + txChannels.evict(); |
| 240 | + assertThat(txChannels.getNumIdle()) |
| 241 | + .isEqualTo(1); |
| 242 | + assertThat(txChannels.getDestroyedByEvictorCount()) |
| 243 | + .isEqualTo(4); |
| 244 | + |
| 245 | + assertThat(swallowedExceptionsCount.get()) |
| 246 | + .isZero(); |
| 247 | + } |
| 248 | + |
| 249 | + private void createAndCloseFiveChannelTxAndChannelNonTx( |
| 250 | + org.springframework.amqp.rabbit.connection.ConnectionFactory connectionFactory) { |
| 251 | + int channelAmount = 5; |
| 252 | + Connection connection = connectionFactory.createConnection(); |
| 253 | + |
| 254 | + List<Channel> channels = new ArrayList<>(channelAmount); |
| 255 | + List<Channel> txChannels = new ArrayList<>(channelAmount); |
| 256 | + |
| 257 | + for (int i = 0; i < channelAmount; i++) { |
| 258 | + channels.add(connection.createChannel(false)); |
| 259 | + txChannels.add(connection.createChannel(true)); |
| 260 | + } |
| 261 | + |
| 262 | + for (int i = 0; i < channelAmount; i++) { |
| 263 | + RabbitUtils.closeChannel(channels.get(i)); |
| 264 | + RabbitUtils.closeChannel(txChannels.get(i)); |
| 265 | + } |
| 266 | + |
| 267 | + connection.close(); |
| 268 | + } |
| 269 | + |
202 | 270 | @Configuration
|
203 | 271 | public static class Config {
|
204 | 272 |
|
|
0 commit comments