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    *   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 }