|
15 | 15 |
|
16 | 16 | package com.rabbitmq.client.impl;
|
17 | 17 |
|
| 18 | +import com.rabbitmq.client.MetricsCollector; |
| 19 | +import com.rabbitmq.client.NoOpMetricsCollector; |
| 20 | +import com.rabbitmq.client.ShutdownSignalException; |
| 21 | +import com.rabbitmq.utility.IntAllocator; |
| 22 | +import org.slf4j.Logger; |
| 23 | +import org.slf4j.LoggerFactory; |
| 24 | + |
18 | 25 | import java.io.IOException;
|
19 | 26 | import java.util.HashMap;
|
20 | 27 | import java.util.HashSet;
|
21 | 28 | import java.util.Map;
|
22 | 29 | import java.util.Set;
|
23 |
| -import java.util.concurrent.CountDownLatch; |
24 |
| -import java.util.concurrent.ExecutorService; |
25 |
| -import java.util.concurrent.Executors; |
26 |
| -import java.util.concurrent.ThreadFactory; |
27 |
| -import java.util.concurrent.TimeUnit; |
28 |
| - |
29 |
| -import com.rabbitmq.client.NoOpMetricsCollector; |
30 |
| -import com.rabbitmq.client.ShutdownSignalException; |
31 |
| -import com.rabbitmq.client.MetricsCollector; |
32 |
| -import com.rabbitmq.utility.IntAllocator; |
| 30 | +import java.util.concurrent.*; |
33 | 31 |
|
34 | 32 | /**
|
35 | 33 | * Manages a set of channels, indexed by channel number (<code><b>1.._channelMax</b></code>).
|
36 | 34 | */
|
37 | 35 | public class ChannelManager {
|
| 36 | + |
| 37 | + private static final Logger LOGGER = LoggerFactory.getLogger(ChannelManager.class); |
| 38 | + |
38 | 39 | /** Monitor for <code>_channelMap</code> and <code>channelNumberAllocator</code> */
|
39 | 40 | private final Object monitor = new Object();
|
40 | 41 | /** Mapping from <code><b>1.._channelMax</b></code> to {@link ChannelN} instance */
|
@@ -97,16 +98,33 @@ public ChannelN getChannel(int channelNumber) {
|
97 | 98 | * Handle shutdown. All the managed {@link com.rabbitmq.client.Channel Channel}s are shutdown.
|
98 | 99 | * @param signal reason for shutdown
|
99 | 100 | */
|
100 |
| - public void handleSignal(ShutdownSignalException signal) { |
| 101 | + public void handleSignal(final ShutdownSignalException signal) { |
101 | 102 | Set<ChannelN> channels;
|
102 | 103 | synchronized(this.monitor) {
|
103 | 104 | channels = new HashSet<ChannelN>(_channelMap.values());
|
104 | 105 | }
|
105 |
| - for (ChannelN channel : channels) { |
106 |
| - releaseChannelNumber(channel); |
107 |
| - channel.processShutdownSignal(signal, true, true); |
108 |
| - shutdownSet.add(channel.getShutdownLatch()); |
109 |
| - channel.notifyListeners(); |
| 106 | + ExecutorService executorService = Executors.newSingleThreadExecutor(); |
| 107 | + try { |
| 108 | + for (final ChannelN channel : channels) { |
| 109 | + releaseChannelNumber(channel); |
| 110 | + Future<?> channelShutdownTask = executorService.submit(new Runnable() { |
| 111 | + @Override |
| 112 | + public void run() { |
| 113 | + channel.processShutdownSignal(signal, true, true); |
| 114 | + shutdownSet.add(channel.getShutdownLatch()); |
| 115 | + } |
| 116 | + }); |
| 117 | + try { |
| 118 | + // FIXME make the timeout configurable |
| 119 | + channelShutdownTask.get(1, TimeUnit.SECONDS); |
| 120 | + } catch (Exception e) { |
| 121 | + LOGGER.warn("Couldn't properly close channel {}", channel.getChannelNumber()); |
| 122 | + } finally { |
| 123 | + channel.notifyListeners(); |
| 124 | + } |
| 125 | + } |
| 126 | + } finally { |
| 127 | + executorService.shutdownNow(); |
110 | 128 | }
|
111 | 129 | scheduleShutdownProcessing();
|
112 | 130 | }
|
|
0 commit comments