1 /*
2 * Copyright 2013 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 * https://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 package io.netty.channel.group;
17
18 import io.netty.bootstrap.ServerBootstrap;
19 import io.netty.buffer.ByteBuf;
20 import io.netty.buffer.ByteBufHolder;
21 import io.netty.buffer.Unpooled;
22 import io.netty.channel.Channel;
23 import io.netty.channel.ChannelHandlerContext;
24 import io.netty.channel.ChannelId;
25 import io.netty.channel.ChannelInboundHandlerAdapter;
26 import io.netty.channel.EventLoop;
27 import io.netty.channel.ServerChannel;
28 import io.netty.util.CharsetUtil;
29 import io.netty.util.concurrent.GlobalEventExecutor;
30
31 import java.util.Set;
32
33 /**
34 * A thread-safe {@link Set} that contains open {@link Channel}s and provides
35 * various bulk operations on them. Using {@link ChannelGroup}, you can
36 * categorize {@link Channel}s into a meaningful group (e.g. on a per-service
37 * or per-state basis.) A closed {@link Channel} is automatically removed from
38 * the collection, so that you don't need to worry about the life cycle of the
39 * added {@link Channel}. A {@link Channel} can belong to more than one
40 * {@link ChannelGroup}.
41 *
42 * <h3>Broadcast a message to multiple {@link Channel}s</h3>
43 * <p>
44 * If you need to broadcast a message to more than one {@link Channel}, you can
45 * add the {@link Channel}s associated with the recipients and call {@link ChannelGroup#write(Object)}:
46 * <pre>
47 * <strong>{@link ChannelGroup} recipients =
48 * new {@link DefaultChannelGroup}({@link GlobalEventExecutor}.INSTANCE);</strong>
49 * recipients.add(channelA);
50 * recipients.add(channelB);
51 * ..
52 * <strong>recipients.write({@link Unpooled}.copiedBuffer(
53 * "Service will shut down for maintenance in 5 minutes.",
54 * {@link CharsetUtil}.UTF_8));</strong>
55 * </pre>
56 *
57 * <h3>Simplify shutdown process with {@link ChannelGroup}</h3>
58 * <p>
59 * If both {@link ServerChannel}s and non-{@link ServerChannel}s exist in the
60 * same {@link ChannelGroup}, any requested I/O operations on the group are
61 * performed for the {@link ServerChannel}s first and then for the others.
62 * <p>
63 * This rule is very useful when you shut down a server in one shot:
64 *
65 * <pre>
66 * <strong>{@link ChannelGroup} allChannels =
67 * new {@link DefaultChannelGroup}({@link GlobalEventExecutor}.INSTANCE);</strong>
68 *
69 * public static void main(String[] args) throws Exception {
70 * {@link ServerBootstrap} b = new {@link ServerBootstrap}(..);
71 * ...
72 * b.childHandler(new MyHandler());
73 *
74 * // Start the server
75 * b.getPipeline().addLast("handler", new MyHandler());
76 * {@link Channel} serverChannel = b.bind(..).sync();
77 * <strong>allChannels.add(serverChannel);</strong>
78 *
79 * ... Wait until the shutdown signal reception ...
80 *
81 * // Close the serverChannel and then all accepted connections.
82 * <strong>allChannels.close().awaitUninterruptibly();</strong>
83 * }
84 *
85 * public class MyHandler extends {@link ChannelInboundHandlerAdapter} {
86 * {@code @Override}
87 * public void channelActive({@link ChannelHandlerContext} ctx) {
88 * // closed on shutdown.
89 * <strong>allChannels.add(ctx.channel());</strong>
90 * super.channelActive(ctx);
91 * }
92 * }
93 * </pre>
94 */
95 public interface ChannelGroup extends Set<Channel>, Comparable<ChannelGroup> {
96
97 /**
98 * Returns the name of this group. A group name is purely for helping
99 * you to distinguish one group from others.
100 */
101 String name();
102
103 /**
104 * Returns the {@link Channel} which has the specified {@link ChannelId}.
105 *
106 * @return the matching {@link Channel} if found. {@code null} otherwise.
107 */
108 Channel find(ChannelId id);
109
110 /**
111 * Writes the specified {@code message} to all {@link Channel}s in this
112 * group. If the specified {@code message} is an instance of
113 * {@link ByteBuf}, it is automatically
114 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
115 * condition. The same is true for {@link ByteBufHolder}. Please note that this operation is asynchronous as
116 * {@link Channel#write(Object)} is.
117 *
118 * @return itself
119 */
120 ChannelGroupFuture write(Object message);
121
122 /**
123 * Writes the specified {@code message} to all {@link Channel}s in this
124 * group that are matched by the given {@link ChannelMatcher}. If the specified {@code message} is an instance of
125 * {@link ByteBuf}, it is automatically
126 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
127 * condition. The same is true for {@link ByteBufHolder}. Please note that this operation is asynchronous as
128 * {@link Channel#write(Object)} is.
129 *
130 * @return the {@link ChannelGroupFuture} instance that notifies when
131 * the operation is done for all channels
132 */
133 ChannelGroupFuture write(Object message, ChannelMatcher matcher);
134
135 /**
136 * Writes the specified {@code message} to all {@link Channel}s in this
137 * group that are matched by the given {@link ChannelMatcher}. If the specified {@code message} is an instance of
138 * {@link ByteBuf}, it is automatically
139 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
140 * condition. The same is true for {@link ByteBufHolder}. Please note that this operation is asynchronous as
141 * {@link Channel#write(Object)} is.
142 *
143 * If {@code voidPromise} is {@code true} {@link Channel#voidPromise()} is used for the writes and so the same
144 * restrictions to the returned {@link ChannelGroupFuture} apply as to a void promise.
145 *
146 * @return the {@link ChannelGroupFuture} instance that notifies when
147 * the operation is done for all channels
148 */
149 ChannelGroupFuture write(Object message, ChannelMatcher matcher, boolean voidPromise);
150
151 /**
152 * Flush all {@link Channel}s in this
153 * group. If the specified {@code messages} are an instance of
154 * {@link ByteBuf}, it is automatically
155 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
156 * condition. Please note that this operation is asynchronous as
157 * {@link Channel#write(Object)} is.
158 *
159 * @return the {@link ChannelGroupFuture} instance that notifies when
160 * the operation is done for all channels
161 */
162 ChannelGroup flush();
163
164 /**
165 * Flush all {@link Channel}s in this group that are matched by the given {@link ChannelMatcher}.
166 * If the specified {@code messages} are an instance of
167 * {@link ByteBuf}, it is automatically
168 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
169 * condition. Please note that this operation is asynchronous as
170 * {@link Channel#write(Object)} is.
171 *
172 * @return the {@link ChannelGroupFuture} instance that notifies when
173 * the operation is done for all channels
174 */
175 ChannelGroup flush(ChannelMatcher matcher);
176
177 /**
178 * Shortcut for calling {@link #write(Object)} and {@link #flush()}.
179 */
180 ChannelGroupFuture writeAndFlush(Object message);
181
182 /**
183 * @deprecated Use {@link #writeAndFlush(Object)} instead.
184 */
185 @Deprecated
186 ChannelGroupFuture flushAndWrite(Object message);
187
188 /**
189 * Shortcut for calling {@link #write(Object)} and {@link #flush()} and only act on
190 * {@link Channel}s that are matched by the {@link ChannelMatcher}.
191 */
192 ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher);
193
194 /**
195 * Shortcut for calling {@link #write(Object, ChannelMatcher, boolean)} and {@link #flush()} and only act on
196 * {@link Channel}s that are matched by the {@link ChannelMatcher}.
197 */
198 ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher, boolean voidPromise);
199
200 /**
201 * @deprecated Use {@link #writeAndFlush(Object, ChannelMatcher)} instead.
202 */
203 @Deprecated
204 ChannelGroupFuture flushAndWrite(Object message, ChannelMatcher matcher);
205
206 /**
207 * Disconnects all {@link Channel}s in this group from their remote peers.
208 *
209 * @return the {@link ChannelGroupFuture} instance that notifies when
210 * the operation is done for all channels
211 */
212 ChannelGroupFuture disconnect();
213
214 /**
215 * Disconnects all {@link Channel}s in this group from their remote peers,
216 * that are matched by the given {@link ChannelMatcher}.
217 *
218 * @return the {@link ChannelGroupFuture} instance that notifies when
219 * the operation is done for all channels
220 */
221 ChannelGroupFuture disconnect(ChannelMatcher matcher);
222
223 /**
224 * Closes all {@link Channel}s in this group. If the {@link Channel} is
225 * connected to a remote peer or bound to a local address, it is
226 * automatically disconnected and unbound.
227 *
228 * @return the {@link ChannelGroupFuture} instance that notifies when
229 * the operation is done for all channels
230 */
231 ChannelGroupFuture close();
232
233 /**
234 * Closes all {@link Channel}s in this group that are matched by the given {@link ChannelMatcher}.
235 * If the {@link Channel} is connected to a remote peer or bound to a local address, it is
236 * automatically disconnected and unbound.
237 *
238 * @return the {@link ChannelGroupFuture} instance that notifies when
239 * the operation is done for all channels
240 */
241 ChannelGroupFuture close(ChannelMatcher matcher);
242
243 /**
244 * @deprecated This method will be removed in the next major feature release.
245 *
246 * Deregister all {@link Channel}s in this group from their {@link EventLoop}.
247 * Please note that this operation is asynchronous as {@link Channel#deregister()} is.
248 *
249 * @return the {@link ChannelGroupFuture} instance that notifies when
250 * the operation is done for all channels
251 */
252 @Deprecated
253 ChannelGroupFuture deregister();
254
255 /**
256 * @deprecated This method will be removed in the next major feature release.
257 *
258 * Deregister all {@link Channel}s in this group from their {@link EventLoop} that are matched by the given
259 * {@link ChannelMatcher}. Please note that this operation is asynchronous as {@link Channel#deregister()} is.
260 *
261 * @return the {@link ChannelGroupFuture} instance that notifies when
262 * the operation is done for all channels
263 */
264 @Deprecated
265 ChannelGroupFuture deregister(ChannelMatcher matcher);
266
267 /**
268 * Returns the {@link ChannelGroupFuture} which will be notified when all {@link Channel}s that are part of this
269 * {@link ChannelGroup}, at the time of calling, are closed.
270 */
271 ChannelGroupFuture newCloseFuture();
272
273 /**
274 * Returns the {@link ChannelGroupFuture} which will be notified when all {@link Channel}s that are part of this
275 * {@link ChannelGroup}, at the time of calling, are closed.
276 */
277 ChannelGroupFuture newCloseFuture(ChannelMatcher matcher);
278 }