|
32 | 32 | import java.util.concurrent.ConcurrentHashMap; |
33 | 33 | import java.util.concurrent.ExecutorService; |
34 | 34 | import java.util.concurrent.Executors; |
| 35 | +import java.util.concurrent.Future; |
35 | 36 | import java.util.concurrent.ThreadFactory; |
| 37 | +import java.util.concurrent.TimeUnit; |
36 | 38 | import java.util.concurrent.TimeoutException; |
37 | 39 | import java.util.concurrent.locks.Lock; |
38 | 40 | import java.util.concurrent.locks.ReentrantLock; |
@@ -638,10 +640,10 @@ private void recoverTopology(final ExecutorService executor) { |
638 | 640 | // We also need to recover 1 type of entity at a time in case channel1 has a binding to a queue that is currently owned and being recovered by channel2 for example |
639 | 641 | // Note: invokeAll will block until all callables are completed and all returned futures will be complete |
640 | 642 | try { |
641 | | - executor.invokeAll(groupEntitiesByChannel(Utility.copy(recordedExchanges).values())); |
642 | | - executor.invokeAll(groupEntitiesByChannel(Utility.copy(recordedQueues).values())); |
643 | | - executor.invokeAll(groupEntitiesByChannel(Utility.copy(recordedBindings))); |
644 | | - executor.invokeAll(groupEntitiesByChannel(Utility.copy(consumers).values())); |
| 643 | + recoverEntitiesAsynchronously(executor, Utility.copy(recordedExchanges).values()); |
| 644 | + recoverEntitiesAsynchronously(executor, Utility.copy(recordedQueues).values()); |
| 645 | + recoverEntitiesAsynchronously(executor, Utility.copy(recordedBindings)); |
| 646 | + recoverEntitiesAsynchronously(executor, Utility.copy(consumers).values()); |
645 | 647 | } catch (final Exception cause) { |
646 | 648 | final String message = "Caught an exception while recovering toplogy: " + cause.getMessage(); |
647 | 649 | final TopologyRecoveryException e = new TopologyRecoveryException(message, cause); |
@@ -748,7 +750,22 @@ private void propagateQueueNameChangeToConsumers(String oldName, String newName) |
748 | 750 | } |
749 | 751 | } |
750 | 752 | } |
751 | | - |
| 753 | + |
| 754 | + private void recoverEntitiesAsynchronously(ExecutorService executor, Collection<? extends RecordedEntity> recordedEntities) throws InterruptedException { |
| 755 | + List<Future<Object>> tasks = executor.invokeAll(groupEntitiesByChannel(recordedEntities)); |
| 756 | + for (Future<Object> task : tasks) { |
| 757 | + if (!task.isDone()) { |
| 758 | + LOGGER.warn("Recovery task should be done {}", task); |
| 759 | + } else { |
| 760 | + try { |
| 761 | + task.get(1, TimeUnit.MILLISECONDS); |
| 762 | + } catch (Exception e) { |
| 763 | + LOGGER.warn("Recovery task is done but returned an exception", e); |
| 764 | + } |
| 765 | + } |
| 766 | + } |
| 767 | + } |
| 768 | + |
752 | 769 | private <E extends RecordedEntity> List<Callable<Object>> groupEntitiesByChannel(final Collection<E> entities) { |
753 | 770 | // map entities by channel |
754 | 771 | final Map<AutorecoveringChannel, List<E>> map = new LinkedHashMap<AutorecoveringChannel, List<E>>(); |
|
0 commit comments