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.ChannelHandlerAdapter;
24  import io.netty.channel.ChannelHandlerContext;
25  import io.netty.channel.ChannelId;
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 ChannelHandlerAdapter} {
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 match 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      * Flush all {@link Channel}s in this
137      * group. If the specified {@code messages} are an instance of
138      * {@link ByteBuf}, it is automatically
139      * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
140      * condition. Please note that this operation is asynchronous as
141      * {@link Channel#write(Object)} is.
142      *
143      * @return the {@link ChannelGroupFuture} instance that notifies when
144      *         the operation is done for all channels
145      */
146     ChannelGroup flush();
147 
148     /**
149      * Flush all {@link Channel}s in this group that match the given {@link ChannelMatcher}.
150      * If the specified {@code messages} are an instance of
151      * {@link ByteBuf}, it is automatically
152      * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race
153      * condition. Please note that this operation is asynchronous as
154      * {@link Channel#write(Object)} is.
155      *
156      * @return the {@link ChannelGroupFuture} instance that notifies when
157      *         the operation is done for all channels
158      */
159     ChannelGroup flush(ChannelMatcher matcher);
160 
161     /**
162      * Shortcut for calling {@link #write(Object)} and {@link #flush()}.
163      */
164     ChannelGroupFuture writeAndFlush(Object message);
165 
166     /**
167      * Shortcut for calling {@link #write(Object)} and {@link #flush()} and only act on
168      * {@link Channel}s that match the {@link ChannelMatcher}.
169      */
170     ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher);
171 
172     /**
173      * Disconnects all {@link Channel}s in this group from their remote peers.
174      *
175      * @return the {@link ChannelGroupFuture} instance that notifies when
176      *         the operation is done for all channels
177      */
178     ChannelGroupFuture disconnect();
179 
180     /**
181      * Disconnects all {@link Channel}s in this group from their remote peers,
182      * that match the given {@link ChannelMatcher}.
183      *
184      * @return the {@link ChannelGroupFuture} instance that notifies when
185      *         the operation is done for all channels
186      */
187     ChannelGroupFuture disconnect(ChannelMatcher matcher);
188 
189     /**
190      * Closes all {@link Channel}s in this group.  If the {@link Channel} is
191      * connected to a remote peer or bound to a local address, it is
192      * automatically disconnected and unbound.
193      *
194      * @return the {@link ChannelGroupFuture} instance that notifies when
195      *         the operation is done for all channels
196      */
197     ChannelGroupFuture close();
198 
199     /**
200      * Closes all {@link Channel}s in this group that match the given {@link ChannelMatcher}.
201      * If the {@link Channel} is  connected to a remote peer or bound to a local address, it is
202      * automatically disconnected and unbound.
203      *
204      * @return the {@link ChannelGroupFuture} instance that notifies when
205      *         the operation is done for all channels
206      */
207     ChannelGroupFuture close(ChannelMatcher matcher);
208 
209     /**
210      * Deregister all {@link Channel}s in this group from their {@link EventLoop}.
211      * Please note that this operation is asynchronous as {@link Channel#deregister()} is.
212      *
213      * @return the {@link ChannelGroupFuture} instance that notifies when
214      * the operation is done for all channels
215      */
216     ChannelGroupFuture deregister();
217 
218     /**
219      * Deregister all {@link Channel}s in this group from their {@link EventLoop} that match the given
220      * {@link ChannelMatcher}. Please note that this operation is asynchronous as {@link Channel#deregister()} is.
221      *
222      * @return the {@link ChannelGroupFuture} instance that notifies when
223      * the operation is done for all channels
224      */
225     ChannelGroupFuture deregister(ChannelMatcher matcher);
226 }