View Javadoc
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 }