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