1 /*
2 * Copyright 2014 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16
17 package io.netty.util.concurrent;
18
19 import java.util.LinkedHashSet;
20 import java.util.Set;
21
22 /**
23 * @deprecated Use {@link PromiseCombiner}
24 *
25 * {@link GenericFutureListener} implementation which consolidates multiple {@link Future}s
26 * into one, by listening to individual {@link Future}s and producing an aggregated result
27 * (success/failure) when all {@link Future}s have completed.
28 *
29 * @param V the type of value returned by the {@link Future}
30 * @param F the type of {@link Future}
31 */
32 @Deprecated
33 public class PromiseAggregator<V, F extends Future<V>> implements GenericFutureListener<F> {
34
35 private final Promise<?> aggregatePromise;
36 private final boolean failPending;
37 private Set<Promise<V>> pendingPromises;
38
39 /**
40 * Creates a new instance.
41 *
42 * @param aggregatePromise the {@link Promise} to notify
43 * @param failPending {@code true} to fail pending promises, false to leave them unaffected
44 */
45 public PromiseAggregator(Promise<Void> aggregatePromise, boolean failPending) {
46 if (aggregatePromise == null) {
47 throw new NullPointerException("aggregatePromise");
48 }
49 this.aggregatePromise = aggregatePromise;
50 this.failPending = failPending;
51 }
52
53 /**
54 * See {@link PromiseAggregator#PromiseAggregator(Promise, boolean)}.
55 * Defaults {@code failPending} to true.
56 */
57 public PromiseAggregator(Promise<Void> aggregatePromise) {
58 this(aggregatePromise, true);
59 }
60
61 /**
62 * Add the given {@link Promise}s to the aggregator.
63 */
64 @SafeVarargs
65 public final PromiseAggregator<V, F> add(Promise<V>... promises) {
66 if (promises == null) {
67 throw new NullPointerException("promises");
68 }
69 if (promises.length == 0) {
70 return this;
71 }
72 synchronized (this) {
73 if (pendingPromises == null) {
74 int size;
75 if (promises.length > 1) {
76 size = promises.length;
77 } else {
78 size = 2;
79 }
80 pendingPromises = new LinkedHashSet<Promise<V>>(size);
81 }
82 for (Promise<V> p : promises) {
83 if (p == null) {
84 continue;
85 }
86 pendingPromises.add(p);
87 p.addListener(this);
88 }
89 }
90 return this;
91 }
92
93 @Override
94 public synchronized void operationComplete(F future) throws Exception {
95 if (pendingPromises == null) {
96 aggregatePromise.setSuccess(null);
97 } else {
98 pendingPromises.remove(future);
99 if (!future.isSuccess()) {
100 Throwable cause = future.cause();
101 aggregatePromise.setFailure(cause);
102 if (failPending) {
103 for (Promise<V> pendingFuture : pendingPromises) {
104 pendingFuture.setFailure(cause);
105 }
106 }
107 } else {
108 if (pendingPromises.isEmpty()) {
109 aggregatePromise.setSuccess(null);
110 }
111 }
112 }
113 }
114
115 }