Returns a list of delegate futures that correspond to the futures received in the order that they complete. Delegate futures return the same value or throw the same exception as the corresponding input future returns/throws. Cancelling a delegate future has no effect on any input future, since t
(Iterable<? extends ListenableFuture<? extends T>> futures)
| 1022 | */ |
| 1023 | |
| 1024 | @Beta |
| 1025 | @GwtIncompatible // TODO |
| 1026 | public static <T> ImmutableList<ListenableFuture<T>> inCompletionOrder(Iterable<? extends ListenableFuture<? extends T>> futures) { |
| 1027 | // A CLQ may be overkill here. We could save some pointers/memory by synchronizing on an |
| 1028 | // ArrayDeque |
| 1029 | final ConcurrentLinkedQueue<SettableFuture<T>> delegates = Queues.newConcurrentLinkedQueue(); |
| 1030 | ImmutableList.Builder<ListenableFuture<T>> listBuilder = ImmutableList.builder(); |
| 1031 | // Using SerializingExecutor here will ensure that each CompletionOrderListener executes |
| 1032 | // atomically and therefore that each returned future is guaranteed to be in completion order. |
| 1033 | // N.B. there are some cases where the use of this executor could have possibly surprising |
| 1034 | // effects when input futures finish at approximately the same time _and_ the output futures |
| 1035 | // have directExecutor listeners. In this situation, the listeners may end up running on a |
| 1036 | // different thread than if they were attached to the corresponding input future. We believe |
| 1037 | // this to be a negligible cost since: |
| 1038 | // 1. Using the directExecutor implies that your callback is safe to run on any thread. |
| 1039 | // 2. This would likely only be noticeable if you were doing something expensive or blocking on |
| 1040 | // a directExecutor listener on one of the output futures which is an antipattern anyway. |
| 1041 | SerializingExecutor executor = new SerializingExecutor(directExecutor()); |
| 1042 | for (final ListenableFuture<? extends T> future : futures) { |
| 1043 | SettableFuture<T> delegate = SettableFuture.create(); |
| 1044 | // Must make sure to add the delegate to the queue first in case the future is already done |
| 1045 | delegates.add(delegate); |
| 1046 | future.addListener( |
| 1047 | new Runnable() { |
| 1048 | @Override |
| 1049 | public void run() { |
| 1050 | delegates.remove().setFuture(future); |
| 1051 | } |
| 1052 | }, |
| 1053 | executor); |
| 1054 | listBuilder.add(delegate); |
| 1055 | } |
| 1056 | return listBuilder.build(); |
| 1057 | } |
| 1058 | |
| 1059 | /** |
| 1060 | * Registers separate success and failure callbacks to be run when the {@code Future}'s |
nothing calls this directly
no test coverage detected